有什么方法可以在C++宏中评估decltype
?我的主要动机是创建一个能够确定this
类型并将其转换为字符串的宏。有没有办法将decltype转换为宏中的字符串?
如果无法使用decltype
还有什么其他方式在类声明中使用的宏可以将类的类型作为字符串?
有什么方法可以在C++宏中评估decltype
?我的主要动机是创建一个能够确定this
类型并将其转换为字符串的宏。有没有办法将decltype转换为宏中的字符串?
如果无法使用decltype
还有什么其他方式在类声明中使用的宏可以将类的类型作为字符串?
有没有什么办法可以在C++宏中评估
decltype
?
没有,因为宏decltype
前严格评估。
据我所知,没有办法让这个班的名字成为一个宏,完全停下来。任何这样的方式都必须由编译器生成的宏支持。
但是,您可以使用typeid
来获取损坏的名称(严格来说,是实现定义的表示形式),然后使用特定于编译器的工具从其中检索取消加载的名称。
例如,GCC提供demangling library来做到这一点。
这里有一个小例子online demo
:
#define THIS_CLASS_NAME() demangled(typeid(*this).name())
std::string demangled(char const* tname) {
std::unique_ptr<char, void(*)(void*)>
name{abi::__cxa_demangle(tname, 0, 0, nullptr), std::free};
return {name.get()};
}
用法:
namespace foo {
template <typename T>
struct bar {
bar() { std::cout << THIS_CLASS_NAME() << '\n'; }
};
}
int main() {
foo::bar<int> b;
}
产量:
foo::bar<int>
宏被扩展,所以很遗憾他们不没有任何类型的概念。
根据您的需要,您也许可以使用traits类。从理论上讲,它比RTTI和typeid在效率和便携性方面要高一些,但它只适用于你明确告诉它的类型。例如:
template <typename T>
struct Traits
{
static const char * TYPE_NAME;
};
// Generic definition as a fall-back:
template <typename T> const char * Traits<T>::TYPE_NAME = "unknown";
// Explicit definitions
template < > const char * Traits<int>::TYPE_NAME = "int";
template < > const char * Traits<float>::TYPE_NAME = "float";
template < > const char * Traits<ExampleClass>::TYPE_NAME = "ExampleClass";
的明确定义是有点麻烦,所以你可以创建一个宏,使他们更容易阅读:
#define DECLARE_TYPE_TRAIT(name) template < > const char * Traits<name>::TYPE_NAME = #name;
DECLARE_TYPE_TRAITS(int)
DECLARE_TYPE_TRAITS(float)
DECLARE_TYPE_TRAITS(ExampleClass)
使用在你的代码的特性类是很容易的。你只需实例化要查找任何类型的特征模板,并访问TYPE_NAME成员:
int foo;
ExampleClass blah;
cout << Traits<decltype(foo)>::TYPE_NAME << endl;
cout << Traits<decltype(blah)>::TYPE_NAME << endl;
谢谢 - 我去,实际上只是使用类型名作为参数传递给宏的解决方案 - 这是有效的与此相同,但更具体到我的具体情况。 –