以下代码在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
这样做吗?
答案 0 :(得分:0)
写下这些:
// for variables:
template<typename T>
char const* GetRawName( T unused ) { ... }
// for types:
template<typename T>
char const* GetRawName() { ... }
在Windows和非Windows上使用#ifdef
块上的不同实现,在您知道要在Microsoft软件编译器中定义的令牌上使用{{1}}块,但在其他编译器中则不行。这将MS和非MS编译版本之间的预处理差异隔离到隔离文件中。
这确实需要对原始代码进行少量更改,但这样做仍然可以在Microsoft软件编译器上进行编译。
答案 1 :(得分:0)
#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
名称与关键字[...] 词汇相同但它合理地工作,并且需要在其他地方进行最少的修改。
答案 2 :(得分:0)
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);