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