有没有办法在宏中将decltype转换为字符串

Is there any way to convert decltype to string in a macro?

本文关键字:decltype 转换 字符串 有没有      更新时间:2023-10-16

有什么方法可以在C++宏中计算decltype吗?我的主要动机是创建一个能够确定this类型并将其转换为字符串的宏。

如果不能使用decltype,那么在类声明中使用的宏是否可以通过其他方式将类的类型获取为字符串?

有什么方法可以在C++宏中评估decltype吗?

否,因为宏在decltype之前是严格求值的。

据我所知,没有办法将类的名称作为宏,句号。任何这样的方式都必须得到编译器生成的宏的支持。

但是,您可以使用typeid来获取损坏的名称(严格来说,是实现定义的表示),然后使用编译器特定的工具从中检索损坏的名称。

例如,GCC提供了解映射库来实现这一点。

以下是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)

在代码中使用traits类非常容易。您只需在要查找的任何类型上实例化traits模板,然后访问type_NAME成员:

int foo;
ExampleClass blah;
cout << Traits<decltype(foo)>::TYPE_NAME << endl;
cout << Traits<decltype(blah)>::TYPE_NAME << endl;