我想找出变量的类型(变量由Template参数给出,所以我不知道它是什么)。
#include <iostream>
#include <typeinfo>
int main()
{
double test;
std::cout << typeid(test).name() << std::endl;
}
但该守则只发出: $。/测试
d
但我需要双倍。
关键是,我不知道期望哪种类型,但我必须在一个子程序中编写它,这个子程序有待编译。所以d是个坏主意。
答案 0 :(得分:3)
如果您知道必须支持的类型列表,您可以编写自己的函数来执行此操作:
template <typename T>
void printtype()
{
if (typeid(T) == typeid(double))
std::cout << "double";
else if (typeid(T) == typeid(int))
std::cout << "int";
}
请注意,由于该函数没有类型为T的参数,因此它必须始终具有明确声明的类型:
printtype<double>()
当然,类型可以是参数类型:
printtype<U>()
答案 1 :(得分:2)
在GNU ABI中,name()
typeid
#include <cxxabi.h>
#include <stdlib.h>
#include <string>
template <typename T> std::string nameofType(const T& v)
{
int status;
char *realname = abi::__cxa_demangle(typeid(v).name(), 0, 0, &status);
std::string name(realname? realname : "????");
free(realname);
return name;
}
<子> 子>
免责声明如果不明显,当然 GNU ABI只支持GNU ABI中的demangling名称(可能甚至没有大不相同的版本)。
{{1}}
答案 2 :(得分:2)
您可以尝试使用该表达式作为参数强制模板中的错误,并且编译器错误消息将具有您寻找的类型。
例如,使用GCC:
#include <map>
#include <string>
template<typename T> void ErrorType(T &t)
{
char x[sizeof(t)==0 ? 1 : -1];
}
template<typename T> void ErrorType(const T &t)
{
char x[sizeof(t)==0 ? 1 : -1];
}
int main()
{
double d = 3;
const double cd = 3;
ErrorType(d);
ErrorType(cd);
ErrorType(3);
std::map<std::string, int> x;
ErrorType(x.begin());
}
$ g++ -c test.cpp
test.cpp: In function ‘void ErrorType(T&) [with T = double]’:
test.cpp:17:20: instantiated from here
test.cpp:6:14: error: size of array is negative
test.cpp: In function ‘void ErrorType(const T&) [with T = double]’:
test.cpp:18:21: instantiated from here
test.cpp:10:14: error: size of array is negative
test.cpp: In function ‘void ErrorType(const T&) [with T = int]’:
test.cpp:19:20: instantiated from here
test.cpp:10:14: error: size of array is negative
test.cpp: In function ‘void ErrorType(const T&) [with T = std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, int> >]’:
test.cpp:22:28: instantiated from here
test.cpp:10:14: error: size of array is negative
所以转储的类型包括double
,int
和std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, int> >
。
第一个重载是非const,这意味着表达式是非const l值。
需要sizeof(t)==0
的技巧来使整个表达式依赖于模板参数,并将错误延迟到实例化。错误本身(数组的大小是负数)当然是没有意义的。
如果您使用的是C ++ 11,则可以改进:
#include <map>
#include <string>
template<typename T> void ErrorType(T &&t)
{
static_assert(sizeof(t)==0, "Reporting type name");
}
int main()
{
double d = 3;
const double cd = 3;
ErrorType(d);
ErrorType(cd);
ErrorType(3);
std::map<std::string, int> x;
ErrorType(x.begin());
}
$ g++ -c test.cpp -std=gnu++0x
test.cpp: In function ‘void ErrorType(T&&) [with T = double&]’:
test.cpp:15:20: instantiated from here
test.cpp:6:9: error: static assertion failed: "Reporting type name"
test.cpp: In function ‘void ErrorType(T&&) [with T = const double&]’:
test.cpp:16:21: instantiated from here
test.cpp:6:9: error: static assertion failed: "Reporting type name"
test.cpp: In function ‘void ErrorType(T&&) [with T = int]’:
test.cpp:17:20: instantiated from here
test.cpp:6:9: error: static assertion failed: "Reporting type name"
test.cpp: In function ‘void ErrorType(T&&) [with T = std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, int> >]’:
test.cpp:20:28: instantiated from here
test.cpp:6:9: error: static assertion failed: "Reporting type name"
作为额外奖励,可以在const l值和r值之间产生差异。第一个是double
l值,第二个是const double
l值,另外两个是r值。
答案 3 :(得分:1)
注意:type_info成员名返回的字符串取决于 您的编译器和库的具体实现。它不是 必须是一个简单的字符串,其典型的类型名称,如在 用于生成此输出的编译器。
我们的编译器在调用type_info :: name中返回了什么 例如,我们的编译器生成了易于理解的名称 由人类,但这不是一个要求:编译器可能只是返回 任何字符串。
来源:http://www.cplusplus.com/doc/tutorial/typecasting/
我的GCC产生了错误的名字。例如。 d代表double
,i代表int
,c代表char
,St6vectorIiSaIiEE代表std::vector<int>
来自GCC的typeinfo:
/** Returns an @e implementation-defined byte string; this is not
* portable between compilers! */
const char* name() const
{ return __name[0] == '*' ? __name + 1 : __name; }
- 编辑 -
您无法“重复”获取编译器之间的名称。如果你想做到这一点,你必须像约翰戈登在他的帖子中描述的那样硬编码。