C++11 有没有一种方法可以在C++;

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:

模板
结构类型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)