由于 typeid().raw_name(),c++ 代码无法使用 GCC 编译 - 我该如何解决这个问题?

Posted

技术标签:

【中文标题】由于 typeid().raw_name(),c++ 代码无法使用 GCC 编译 - 我该如何解决这个问题?【英文标题】:c++ code won't compile with GCC because of typeid().raw_name() - how can I fix this? 【发布时间】:2012-11-27 15:14:54 【问题描述】:

以下代码在 Windows 上使用 Visual Studio 编译良好:

class_handle(base *ptr) : ptr_m(ptr), name_m(typeid(base).raw_name())  signature_m = CLASS_HANDLE_SIGNATURE; 

如果我尝试在 Linux 上编译相同的代码,我会得到:

error: ‘const class std::type_info’ has no member named ‘raw_name’

据我了解,raw_name 是 Microsoft specific 的实现。我必须如何更改我的代码才能在 Windows 和 Linux 系统上编译?

EDIT1 我宁愿不修改原始代码,我只需要一个解决方法来使用 gcc 编译。这可能吗?

EDIT2#define raw_name name 解决问题吗?

【问题讨论】:

切换到name() 好吗? @R.MartinhoFernandes 我宁愿不修改原始代码。有什么解决方法吗? @memyself 没有干净、符合标准的解决方法。 (你可以重新#defineraw_name 但这样做会让你进入一个特别的地狱)。此外,没有必要使用raw_name,所以我会从代码库中完全禁止它。 @KonradRudolph 所以我不应该这样做#define raw_name name @memyself 我只会在我可以将其范围严格限制在这个代码位置(在包含该代码后直接#undefing)的情况下才这样做,即使这样,也只有在有令人信服的理由的情况下不要修改原始代码(是的,我知道个理由不这样做)。 【参考方案1】:

写下这些:

// for variables:
template<typename T>
char const* GetRawName( T unused )  ... 
// for types:
template<typename T>
char const* GetRawName()  ... 

在 Windows 和非 Windows 上使用不同的实现,在您知道在 microsoft 编译器中定义的令牌上使用 #ifdef 块,但在您的其他编译器中没有。这会将 MS 和非 MS 编译版本之间的预处理差异隔离到一个独立的文件中。

这确实需要对原始代码进行少量更改,但这样做的方式仍然可以在 microsoft 编译器上编译。

【讨论】:

【参考方案2】:

#define typeid 可能更安全:

class compat_typeinfo 
  const std::type_info &ti;
public:
  explicit compat_typeinfo(const std::type_info &ti): ti(ti) 
  const char *name() const  return ti.name(); 
  const char *raw_name() const  return ti.name(); 
;
compat_typeinfo compat_typeid(const std::type_info &ti) 
  return compat_typeinfo(ti);

#define typeid(x) compat_typeid(typeid(x))

当然,这在 17.6.4.3.1p2 中是非法的(翻译单元不得 #define#undef 名称在词法上与关键字相同 [...])但很有可能工作,并且需要在其他地方进行最少的修改。

【讨论】:

也许更安全。但无效(不允许重新定义关键字词)。 .name() 返回去错名字,.raw_name() 返回去错名字。【参考方案3】:

GCC 没有定义raw_name,但在cxxabi.h 中包含了重整/去重。你可以看到它的一个例子here。

#include <cxxabi.h>
//...
std::bad_exception  e;
realname = abi::__cxa_demangle(e.what(), 0, 0, &status);
std::cout << e.what() << "\t=> " << realname << "\t: " << status << '\n';
free(realname);

【讨论】:

以上是关于由于 typeid().raw_name(),c++ 代码无法使用 GCC 编译 - 我该如何解决这个问题?的主要内容,如果未能解决你的问题,请参考以下文章

C/C++ 判断一个变量的类型(typeid)

C ++ 17中的typeid有反函数吗?

c++filt 不会对 typeid 名称进行分解

C++ 强制转换和 typeid

在C ++ 17中是否有针对typeid的逆函数?

是否有引用的typeid?