C ++中是否有__CLASS__macros?

在C ++中是否有一个__CLASS__macros,它给出类似于__FUNCTION__macros的类名,它给出了函数名

最接近的就是调用typeid(your_class).name() – 但是这会产生编译器特定的错位名称。

在类中使用它只是typeid(*this).name()

使用typeid(*this).name()是在静态方法调用中没有this指针。 macros__PRETTY_FUNCTION__在静态函数和方法调用中报告类名。 但是,这只会使用gcc。

以下是通过macros样式界面提取信息的示例。

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

macros__METHOD_NAME__将返回一个forms为<class>::<method>()的string,从__PRETTY_FUNCTION__给出的值中修剪返回types,修饰符和参数。

对于只提取class级名称的东西,必须小心,以避免没有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__) 

还没。 (我认为__class__是在某处提出的)。 您也可以尝试从__PRETTY_FUNCTION__提取类部件。

我想build议boost :: typeindex ,我从Scott Meyer的“Effective Modern C ++”中了解到这里有一个基本的例子:

 #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's 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's type is : " << bti::type_id_with_cvr<decltype(fb)>().pretty_name() << "\n"; } 

用“g ++ –std = c ++ 14”编译,产生以下内容

产量

如果你想打印一个模板types,那很简单。

T =双倍

要从对象实例中获取它,只需使用decltype:

fb的types是:foo_bar

我认为使用__PRETTY_FUNCTION__是足够好的,虽然它包括命名空间以及namespace::classname::functionname直到__CLASS__可用。

如果你的编译器碰巧是g++而你要求__CLASS__因为你需要一种方法来获取当前的方法名,包括类, __PRETTY_FUNCTION__应该有帮助(根据info gcc 5.43函数名string )。

如果你在说MS C ++(你应该说明,尤其是__FUNCTION__是一个非标准的扩展),有__FUNCDNAME____FUNCSIG__符号可以parsing

你可以得到包含类名的函数名。 这可以处理C型function。

 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) + "()"; } 

我的解决scheme

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

我为Visual C ++ 12工作。

以下是基于__FUNCTION__macros和C ++模板的解决scheme:

 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(); } 

这是一个如何可以用于logging器类的例子

 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); } } 

Example::Run的输出将会是

 Example: 0 Logger<Example>: 0 

如果你愿意支付一个指针的成本,这很好地工作。

 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__ ) {}; }; 

与msvc和gcc一起工作

 #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 

下面的方法(基于上面的methodName())也可以处理像“int main(int argc,char ** argv)”这样的input:

 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) + "()"; }