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

Is there any way to evaluate decltype in a C ++ macro? My main motivation is to create a macro that can determine the type of this and convert it to a string.

If decltype cannot be used in another way, can the macro used inside the class declaration get the class type as a string?

+4
source share
2 answers

Is there any way to evaluate decltype in a C ++ macro?

No, because macros are strictly evaluated before decltype .

As far as I know, there is no way to get the class name as a macro, stop completely. Any such method must be supported by a macro created by the compiler.

However, you can use typeid to get a malformed name (strictly speaking, a representation defined by an implementation), and then use compiler-specific tools to extract the unmarshaled name from it.

For example, GCC offers a demangling library for this.

Here is a minimal example of an 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()}; } 

Using:

 namespace foo { template <typename T> struct bar { bar() { std::cout << THIS_CLASS_NAME() << '\n'; } }; } int main() { foo::bar<int> b; } 

Productivity:

 foo::bar<int> 
+4
source

Macros expand to compile any code, so unfortunately they have no concept of types.

Depending on your needs, you may be able to use a feature class. It is theoretically more efficient and portable than RTTI and typeid, but it only works for types that you explicitly talked about. For instance:

 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"; 

Explicit definitions are a bit cumbersome, so you can create a macro to make them more readable:

 #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) 

Using the feature class in your code is very simple. You simply create a property template for any type you want to find, and access the TYPE_NAME member:

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

Source: https://habr.com/ru/post/1490248/


All Articles