由于 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 没有干净、符合标准的解决方法。 (你可以重新#define
raw_name
但这样做会让你进入一个特别的地狱)。此外,没有必要使用raw_name
,所以我会从代码库中完全禁止它。
@KonradRudolph 所以我不应该这样做#define raw_name name
?
@memyself 我只会在我可以将其范围严格限制在这个代码位置(在包含该代码后直接#undef
ing)的情况下才这样做,即使这样,也只有在有令人信服的理由的情况下不要修改原始代码(是的,我知道有个理由不这样做)。
【参考方案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 编译 - 我该如何解决这个问题?的主要内容,如果未能解决你的问题,请参考以下文章