使用GCC编译没有RTTI的时间typeid

Kyl*_*yle 18 c++ reflection

无论如何,在typeid禁用RTTI的情况下从GCC 获取编译时信息?在Visual Studio下const char* typeName = typeid(int).name();,即使禁用了RTTI ,一个简单的命令也会适当地返回"int".不幸的是,海湾合作委员会不能这样做.当我尝试在typeid没有RTTI的情况下打电话时,我的程序崩溃了.我知道禁用RTTI不是标准的一部分,但无论如何我是否可以强制GCC进行已知类型的编译时间分辨率?

出于性能原因,RTTI被禁用.我不需要运行时RTTI.

编辑:

这就是我最终的目标:

template<typename T> const char* TypeName(void);
template<typename T> const char* TypeName(T type) { return TypeName<T>(); }

#define REFLECTION_REGISTER_TYPE(type) \
    template <> const char* TypeName<type>(void) { return #type; } 
Run Code Online (Sandbox Code Playgroud)

它需要REFLECTION_REGISTER_TYPE为每个需要反射信息的类型调用.但只要它被称为每个必需的类型,调用TypeName<int>工作完美.我还添加了函数TypeName(T type),这意味着你可以做这样的事情:int x = 0; printf(TypeName(x));它将打印出"int".GCC应该能够像VC++一样在编译时实现这一点.

Cat*_*lus 6

不.RTTI是RunTime类型信息(并且禁用它是愚蠢的,但是嘿),这就是目的typeid.如果要在编译时对类型名称进行字符串化,则必须自己进行(通过模板或宏).

  • 我永远不会理解为什么C++没有这个功能.比RTTI更有用. (9认同)
  • 我想做这样的事情:`struct S {int a,b; const char*aType = typeid(S :: a).name();`这是所有编译时信息.虽然我可以简单地指定`a`是一个`int`,但我宁愿让编译器去做.这将使我的代码更加冗长.VC编译器可以做到这一点,我不确定是否有办法让GCC也这样做. (3认同)
  • 我会小心地称其为“愚蠢”。特别是如果您在 MCU 上有大量模板化代码和 256 kB 闪存可用,您不想将其中一半浪费在您从未使用过的模板名称字符串上。x86_64 之外还有世界! (2认同)

Den*_*ose 5

首先,重新打开RTTI。

失败了,如果您真的真的需要一个没有它的类型的字符串表示形式,需要一点点字符串操作,并仔细考虑您编写的非标准代码可能会在升级GCC时中断的事实,或更改平台,或使用其他选项集,您也许可以伪造它。

#include <iostream>
#include <string>

std::string extract_type_name(const char* s) {
  //add logic her
  return s;
}

template<typename T>
std::string type_name() {
  static std::string s = extract_type_name(__PRETTY_FUNCTION__);
  return s;
}

int main() {
  std::cout << type_name<int>() << " " << type_name<std::string>() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

该功能在ideone上的输出为

std::string type_name() [with T = int]
std::string type_name() [with T = std::basic_string<char, std::char_traits<char>, std::allocator<char> >]
Run Code Online (Sandbox Code Playgroud)

假设__PRETTY_FUNCTION__在关闭RTTI的情况下表现相同,将T = blah位拉出来应该不会太困难。

另外,请记住,它typeid(blah).name()提供的保证很少。我记得在一个平台上使用了该平台,任何用户定义类型的结果都是struct。不太有用。即使打开了RTTI,也要靠它来做些脆弱[无论如何都应该这样做]。


ara*_*aud 5

还有另一种解决方案,它的优点和缺点是:

typedef void* TypeId;
template<class T>
TypeId TypeIdNoRTTI() //this function is instantiated for every different type
{
    //WARNING: works only inside one module: same type coming from different module will have different value!
    static T* TypeUniqueMarker = NULL; //thus this static variable will be created for each TypeIdNoRTTI<T> separately
    return &TypeUniqueMarker; //it's address is unique identifier of TypeIdNoRTTI<T> type
}
Run Code Online (Sandbox Code Playgroud)