Is there a __CLASS__ macro in C ++?

Is there a __CLASS__ macro in C ++ that gives a class name, similar to a __FUNCTION__ macro that gives a function name

+71
c ++ macros
Nov 03 '09 at 11:42
source share
13 answers

The closest thing to do is to call typeid(your_class).name() - but this creates a specific name for the compiler.

To use it inside the class just typeid(*this).name()

+49
Nov 03 '09 at 11:44
source share

The problem with using typeid(*this).name() is that there is no this pointer in the call to the static method. The __PRETTY_FUNCTION__ macro reports the class name in static functions, as well as method calls. However, this will only work with gcc.

Here is an example of retrieving information through a macro style interface.

 inline std::string methodName(const std::string& prettyFunction) { size_t colons = prettyFunction.find("::"); size_t begin = prettyFunction.substr(0,colons).rfind(" ") + 1; size_t end = prettyFunction.rfind("(") - begin; return prettyFunction.substr(begin,end) + "()"; } #define __METHOD_NAME__ methodName(__PRETTY_FUNCTION__) 

The __METHOD_NAME__ macro will return the form string <class>::<method>() , truncate the return type, modifiers and arguments from what __PRETTY_FUNCTION__ gives.

For something that only retrieves the class name, care must be taken to avoid situations where there is no class:

 inline std::string className(const std::string& prettyFunction) { size_t colons = prettyFunction.find("::"); if (colons == std::string::npos) return "::"; size_t begin = prettyFunction.substr(0,colons).rfind(" ") + 1; size_t end = colons - begin; return prettyFunction.substr(begin,end); } #define __CLASS_NAME__ className(__PRETTY_FUNCTION__) 
+55
Apr 02 '13 at 22:24
source share

Not yet. (I think __class__ suggested somewhere). You can also try to extract part of the class from __PRETTY_FUNCTION__ .

+9
Nov 03 '09 at 11:46
source share

I would suggest boost :: typeindex , which I learned from Scott Meyer "Effective Modern C ++." Here is a basic example:

Example

 #include <boost/type_index.hpp> class foo_bar { int whatever; }; namespace bti = boost::typeindex; template <typename T> void from_type(T t) { std::cout << "\tT = " << bti::type_id_with_cvr<T>().pretty_name() << "\n"; } int main() { std::cout << "If you want to print a template type, that easy.\n"; from_type(1.0); std::cout << "To get it from an object instance, just use decltype:\n"; foo_bar fb; std::cout << "\tfb type is : " << bti::type_id_with_cvr<decltype(fb)>().pretty_name() << "\n"; } 

Compiled with "g ++ --std = C ++ 14", this calls the following

Exit

If you want to print a template type, this is easy.

T = double

To get it from an object instance, simply use decltype:

Fb type: foo_bar

+7
Aug 27 '15 at 13:27
source share

I think using __PRETTY_FUNCTION__ is good enough, although it does include a namespace as well as ie namespace::classname::functionname until there is __CLASS__ .

+4
Apr 29 '13 at 3:37 on
source share

If your compiler turns out to be g++ and you request __CLASS__ because you need a way to get the current method name, including the class, __PRETTY_FUNCTION__ should help (according to info gcc , section 5.43 Names as Strings Function).

+3
Nov 03 '09 at 11:52
source share

If you are talking about MS C ++ (you must specify esp as __FUNCTION__ is a non-standard extension), there are __FUNCDNAME__ and __FUNCSIG__ characters that you could __FUNCSIG__

+2
Nov 03 '09 at 11:48
source share

You can get the name of the function, including the class name. This can handle C-type functions.

 static std::string methodName(const std::string& prettyFunction) { size_t begin,end; end = prettyFunction.find("("); begin = prettyFunction.substr(0,end).rfind(" ") + 1; end -= begin; return prettyFunction.substr(begin,end) + "()"; } 
+1
May 14 '13 at 3:19
source share

My decision:

 std::string getClassName(const char* fullFuncName) { std::string fullFuncNameStr(fullFuncName); size_t pos = fullFuncNameStr.find_last_of("::"); if (pos == std::string::npos) { return ""; } return fullFuncNameStr.substr(0, pos-1); } #define __CLASS__ getClassName(__FUNCTION__) 

I am working for Visual C ++ 12.

+1
Nov 14 '14 at 9:21
source share

Here's a solution based on __FUNCTION__ and C ++ patterns:

 template <class T> class ClassName { public: static std::string Get() { // Get function name, which is "ClassName<class T>::Get" // The template parameter 'T' is the class name we're looking for std::string name = __FUNCTION__; // Remove "ClassName<class " ("<class " is 7 characters long) size_t pos = name.find_first_of('<'); if (pos != std::string::npos) name = name.substr(pos + 7); // Remove ">::Get" pos = name.find_last_of('>'); if (pos != std::string::npos) name = name.substr(0, pos); return name; } }; template <class T> std::string GetClassName(const T* _this = NULL) { return ClassName<T>::Get(); } 

Here is an example of how this can be used for the logger class

 template <class T> class Logger { public: void Log(int value) { std::cout << GetClassName<T>() << ": " << value << std::endl; std::cout << GetClassName(this) << ": " << value << std::endl; } }; class Example : protected Logger<Example> { public: void Run() { Log(0); } } 

The result of Example::Run will then be

 Example: 0 Logger<Example>: 0 
+1
Jan 22 '15 at 12:29
source share

This works pretty well if you are willing to pay the cost of a pointer.

 class State { public: State( const char* const stateName ) :mStateName( stateName ) {}; const char* const GetName( void ) { return mStateName; } private: const char * const mStateName; }; class ClientStateConnected : public State { public: ClientStateConnected( void ) : State( __FUNCTION__ ) {}; }; 
0
Apr 26 '15 at 6:44
source share

Works with msvc and gcc too

 #ifdef _MSC_VER #define __class_func__ __FUNCTION__ #endif #ifdef __GNUG__ #include <cxxabi.h> #include <execinfo.h> char *class_func(const char *c, const char *f) { int status; static char buff[100]; char *demangled = abi::__cxa_demangle(c, NULL, NULL, &status); snprintf(buff, sizeof(buff), "%s::%s", demangled, f); free(demangled); return buff; } #define __class_func__ class_func(typeid(*this).name(), __func__) #endif 
0
Nov 19 '15 at 10:52
source share

The following method (based on the Name () method above) can also handle input like "int main (int argc, char ** argv)":

 string getMethodName(const string& prettyFunction) { size_t end = prettyFunction.find("(") - 1; size_t begin = prettyFunction.substr(0, end).rfind(" ") + 1; return prettyFunction.substr(begin, end - begin + 1) + "()"; } 
0
Feb 09 '17 at 13:01
source share



All Articles