例如:
int a = 12;
cout << typeof(a) << endl;
预期的输出:
int
例如:
int a = 12;
cout << typeof(a) << endl;
预期的输出:
int
当前回答
非常丑陋,但如果你只想要编译时信息(例如调试):
auto testVar = std::make_tuple(1, 1.0, "abc");
decltype(testVar)::foo= 1;
返回:
Compilation finished with errors:
source.cpp: In function 'int main()':
source.cpp:5:19: error: 'foo' is not a member of 'std::tuple<int, double, const char*>'
其他回答
#include <iostream>
#include <typeinfo>
using namespace std;
#define show_type_name(_t) \
system(("echo " + string(typeid(_t).name()) + " | c++filt -t").c_str())
int main() {
auto a = {"one", "two", "three"};
cout << "Type of a: " << typeid(a).name() << endl;
cout << "Real type of a:\n";
show_type_name(a);
for (auto s : a) {
if (string(s) == "one") {
cout << "Type of s: " << typeid(s).name() << endl;
cout << "Real type of s:\n";
show_type_name(s);
}
cout << s << endl;
}
int i = 5;
cout << "Type of i: " << typeid(i).name() << endl;
cout << "Real type of i:\n";
show_type_name(i);
return 0;
}
输出:
Type of a: St16initializer_listIPKcE
Real type of a:
std::initializer_list<char const*>
Type of s: PKc
Real type of s:
char const*
one
two
three
Type of i: i
Real type of i:
int
您可以使用模板。
template <typename T> const char* typeof(T&) { return "unknown"; } // default
template<> const char* typeof(int&) { return "int"; }
template<> const char* typeof(float&) { return "float"; }
在上面的例子中,当类型不匹配时,它将打印“unknown”。
正如Scott Meyers在《Effective Modern c++》中所解释的那样,
对std::type_info::name的调用不能保证返回任何有意义的东西。
最好的解决方案是让编译器在类型推断期间生成错误消息,例如:
template<typename T>
class TD;
int main(){
const int theAnswer = 32;
auto x = theAnswer;
auto y = &theAnswer;
TD<decltype(x)> xType;
TD<decltype(y)> yType;
return 0;
}
根据不同的编译器,结果会是这样的:
test4.cpp:10:21: error: aggregate ‘TD<int> xType’ has incomplete type and cannot be defined TD<decltype(x)> xType;
test4.cpp:11:21: error: aggregate ‘TD<const int *> yType’ has incomplete type and cannot be defined TD<decltype(y)> yType;
因此,我们知道x的类型是int, y的类型是const int*
Howard Hinnant使用魔法数字提取类型名称。康桓瑋建议字符串前缀和后缀。但是前缀/后缀一直在变化。 使用" probe_type " type_name自动计算" probe_type "的前缀和后缀大小,以提取类型名称:
#include <string_view>
using namespace std;
namespace typeName {
template <typename T>
constexpr string_view wrapped_type_name () {
#ifdef __clang__
return __PRETTY_FUNCTION__;
#elif defined(__GNUC__)
return __PRETTY_FUNCTION__;
#elif defined(_MSC_VER)
return __FUNCSIG__;
#endif
}
class probe_type;
constexpr string_view probe_type_name ("typeName::probe_type");
constexpr string_view probe_type_name_elaborated ("class typeName::probe_type");
constexpr string_view probe_type_name_used (wrapped_type_name<probe_type> ().find (probe_type_name_elaborated) != -1 ? probe_type_name_elaborated : probe_type_name);
constexpr size_t prefix_size () {
return wrapped_type_name<probe_type> ().find (probe_type_name_used);
}
constexpr size_t suffix_size () {
return wrapped_type_name<probe_type> ().length () - prefix_size () - probe_type_name_used.length ();
}
template <typename T>
string_view type_name () {
constexpr auto type_name = wrapped_type_name<T> ();
return type_name.substr (prefix_size (), type_name.length () - prefix_size () - suffix_size ());
}
}
#include <iostream>
using typeName::type_name;
using typeName::probe_type;
class test;
int main () {
cout << type_name<class test> () << endl;
cout << type_name<const int*&> () << endl;
cout << type_name<unsigned int> () << endl;
const int ic = 42;
const int* pic = ⁣
const int*& rpic = pic;
cout << type_name<decltype(ic)> () << endl;
cout << type_name<decltype(pic)> () << endl;
cout << type_name<decltype(rpic)> () << endl;
cout << type_name<probe_type> () << endl;
}
输出
gcc 10.2:
test
const int *&
unsigned int
const int
const int *
const int *&
typeName::probe_type
铿锵声11.0.0:
test
const int *&
unsigned int
const int
const int *
const int *&
typeName::probe_type
VS 2019版本16.7.6:
class test
const int*&
unsigned int
const int
const int*
const int*&
class typeName::probe_type
我喜欢Nick的方法,一个完整的表单可能是这样的(对于所有基本数据类型):
template <typename T> const char* typeof(T&) { return "unknown"; } // default
template<> const char* typeof(int&) { return "int"; }
template<> const char* typeof(short&) { return "short"; }
template<> const char* typeof(long&) { return "long"; }
template<> const char* typeof(unsigned&) { return "unsigned"; }
template<> const char* typeof(unsigned short&) { return "unsigned short"; }
template<> const char* typeof(unsigned long&) { return "unsigned long"; }
template<> const char* typeof(float&) { return "float"; }
template<> const char* typeof(double&) { return "double"; }
template<> const char* typeof(long double&) { return "long double"; }
template<> const char* typeof(std::string&) { return "String"; }
template<> const char* typeof(char&) { return "char"; }
template<> const char* typeof(signed char&) { return "signed char"; }
template<> const char* typeof(unsigned char&) { return "unsigned char"; }
template<> const char* typeof(char*&) { return "char*"; }
template<> const char* typeof(signed char*&) { return "signed char*"; }
template<> const char* typeof(unsigned char*&) { return "unsigned char*"; }