C++11 有没有一种方法可以在C++;
我可以通过以下方式创建唯一的类型id:C++11 有没有一种方法可以在C++;,c++11,C++11,我可以通过以下方式创建唯一的类型id: 模板 结构类型ID { 静态大小\u t值() { 返回reinterpret_cast(&TypeId::value); } }; auto intType=TypeId::value(); 它在运行时工作,但有没有办法在编译时工作? 我想在如下switch语句中使用它: 开关(类型ID) { 大小写类型ID::value(): //做点什么 打破 大小写类型ID::value(): //做点什么 打破 大小写类型ID::value(): //做点什么
模板
结构类型ID
{
静态大小\u t值()
{
返回reinterpret_cast(&TypeId::value);
}
};
auto intType=TypeId::value();
它在运行时工作,但有没有办法在编译时工作?
我想在如下switch语句中使用它:
开关(类型ID)
{
大小写类型ID::value():
//做点什么
打破
大小写类型ID::value():
//做点什么
打破
大小写类型ID::value():
//做点什么
打破
}
这里的问题是,我无法在编译时将指针转换为大小:
模板
结构类型ID
{
静态constexpr size\u t value()
{
返回reinterpret_cast(&TypeId::value);
}
};
constexpr auto id=TypeId::value();
上面的示例给出了以下错误:
错误:从常量表达式中的指针类型“size\t(*)(也称为长无符号int(*)(也称为长无符号int(*))转换为算术类型“size\t{称为长无符号int}”
constexpr auto id=TypeId::value();
更新
我想理解为什么在constexpr中返回地址是好的,但将其转换为int则不是。编译以下代码(但我不能在switch语句中使用指针):
模板
结构类型ID
{
静态constexpr void*值()
{
返回reinterpret_cast(&TypeId::value);
}
};
constexpr void*id=TypeId::value();
这听起来像是一个错误。如果您想获得编译时类型信息,那么可以使用编译时方法来实现。正确的方法是使用
if(std::is_same::value){
//做点什么
}else if(std::is_same::value){
//做点别的
} // ...
这可能会导致某些问题。如果在您的条件中对特定类型使用方法,如std::string::length()
,则会出现编译错误。有几种方法可以解决这个问题:
使用
用于创建依赖于类型的模板专用化
如果只有指针类型问题,则必须重新解释所有指向T
<>目前C++没有自动分配唯一整数类型ID并使其可用编译时间的方法。
这就是需要它的库使用手动类型注册的原因,例如:
template<class T> struct TypeId;
#define REGISTER_TYPE_ID(T, id_value) template<> struct TypeId<T> { static constexpr int id = id_value; };
REGISTER_TYPE_ID(bool, 1)
REGISTER_TYPE_ID(char, 2)
REGISTER_TYPE_ID(unsigned char, 3)
REGISTER_TYPE_ID(unsigned short, 4)
REGISTER_TYPE_ID(unsigned int, 5)
REGISTER_TYPE_ID(unsigned long, 6)
REGISTER_TYPE_ID(unsigned long long, 7)
REGISTER_TYPE_ID(signed char, 8)
REGISTER_TYPE_ID(signed short, 9)
REGISTER_TYPE_ID(signed int, 10)
REGISTER_TYPE_ID(signed long, 11)
REGISTER_TYPE_ID(signed long long, 12)
REGISTER_TYPE_ID(float, 13)
REGISTER_TYPE_ID(double, 14)
REGISTER_TYPE_ID(long double, 15)
模板结构类型id;
#定义寄存器类型ID(T,ID值)模板结构类型ID{static constexpr int ID=ID值;};
寄存器类型标识(bool,1)
寄存器类型标识(字符,2)
寄存器类型ID(无符号字符,3)
寄存器类型标识(无符号短,4)
寄存器类型ID(无符号整数,5)
寄存器类型ID(无符号长,6)
寄存器类型ID(无符号长,7)
寄存器类型ID(签名字符,8)
寄存器类型ID(短签名,9)
寄存器类型ID(签名整数,10)
寄存器类型ID(长签名,11)
寄存器类型ID(有符号长,12)
寄存器类型ID(浮动,13)
寄存器类型ID(双精度,14)
寄存器类型ID(长双精度,15)
不,通常没有办法做到这一点。您可以尝试编译时对\uuuuuuuu文件
、\uuuuu行
、\uuuuu日期
和\uuuuu时间
进行哈希运算,但当然可能会发生冲突。不是说必须使用面向用户的宏(yikes)。现在来看有趣的部分:您是否正在尝试重新实现std::visitor
?不要;)@n、 不,我想在我的库和C#绑定之间传递类型ID。那么,为什么这些东西的非常量会阻止您将它们传递给C#呢?为什么需要case-TypeId::value()
这样做?因此缺少的链接是编译时的自动增量:)?@AlexandreA。尝试跨共享库自动侵权<代码>计数器宏在有限的情况下工作。
template<class T> struct TypeId;
#define REGISTER_TYPE_ID(T, id_value) template<> struct TypeId<T> { static constexpr int id = id_value; };
REGISTER_TYPE_ID(bool, 1)
REGISTER_TYPE_ID(char, 2)
REGISTER_TYPE_ID(unsigned char, 3)
REGISTER_TYPE_ID(unsigned short, 4)
REGISTER_TYPE_ID(unsigned int, 5)
REGISTER_TYPE_ID(unsigned long, 6)
REGISTER_TYPE_ID(unsigned long long, 7)
REGISTER_TYPE_ID(signed char, 8)
REGISTER_TYPE_ID(signed short, 9)
REGISTER_TYPE_ID(signed int, 10)
REGISTER_TYPE_ID(signed long, 11)
REGISTER_TYPE_ID(signed long long, 12)
REGISTER_TYPE_ID(float, 13)
REGISTER_TYPE_ID(double, 14)
REGISTER_TYPE_ID(long double, 15)