有什麼方法可以在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;
謝謝 - 我去,實際上只是使用類型名作爲參數傳遞給宏的解決方案 - 這是有效的與此相同,但更具體到我的具體情況。 –