是否有__CLASS__
宏C++这提供了一种类似于__FUNCTION__
宏类名这给函数名是否有C++一个__CLASS__宏?
回答
有最接近的事就是打电话typeid(your_class).name()
- 但这会产生编译器的具体重整名称。
要使用它的内部类只是typeid(*this).name()
尚未。 (我认为__class__
是在某处提出的)。您也可以尝试从__PRETTY_FUNCTION__
中提取课程部分。
如果你在谈论微软的C++(应该说明,尤指__FUNCTION__
是一个非标准扩展),有__FUNCDNAME__
and __FUNCSIG__
symbols,你可以解析
如果编译器恰好是g++
和你所要求的__CLASS__
因为你想办法让当前的方法名,包括类,__PRETTY_FUNCTION__
应(根据info gcc
,部分5.43函数名称作为字符串)帮助。
使用typeid(*this).name()
的问题是在静态方法调用中没有this
指针。宏__PRETTY_FUNCTION__
报告在静态函数和方法调用的类名。但是,这只会与gcc一起使用。
这里是通过提取宏风格的界面信息的一个例子。
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__)
宏__METHOD_NAME__
将返回形式<class>::<method>()
的字符串,从什么__PRETTY_FUNCTION__
给你修剪的返回类型,修饰符和参数。
对于一些中提取只是类的名称,有些必须小心陷阱的情况下没有课:
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__)
我认为使用__PRETTY_FUNCTION__
是不够好,尽管它包含命名空间以及即namespace::classname::functionname
直到__CLASS__
可用。
你可以得到包含类名的函数名。 这可以处理C型功能。
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) + "()";
}
我的解决办法:
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__
宏观和C++模板的溶液:
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();
}
下面是如何可以被用于记录器类
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
请注意,如果你有一个指向基的指针(这可能是好的),这将不考虑多态。 – 2015-01-22 12:31:38
这个工程相当不错,如果你愿意支付指针的成本。
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__) {};
};
我想建议boost::typeindex,这是我了解到的,斯科特·迈尔的 “有效的现代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“产生以下内容
输出
如果要打印模板类型,那很简单。
T =双
从一个对象实例得到它,只需使用decltype:
FB的类型是:foo_bar这样
是否有可能得到没有名称空间的类名?又名http://coliru.stacked-crooked.com/a/cf1b1a865bb7ecc7 – tower120 2016-02-18 16:31:18
与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)”这样的输入:
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) + "()";
}
- 1. 是否有一个if-clojurescript宏?
- 2. 是否有一个宏的前缀和引用C宏参数的一个宏的方法
- 3. C是否有更多的宏像NULL?
- 4. 是否有可能向另一个宏评估多个参数?
- 5. 是否有一个C预处理器宏来打印出结构?
- 6. 是否有一个Erwin宏拔出表评论/定义?
- 7. 使用Eclipse,是否有一个“全部”宏/函数
- 8. 测试C宏的值是否为空
- 9. C宏:#if检查是否相等
- 10. &符号在一个C宏
- 11. 在C宏扩展期间,是否有扩展为“/ *”的宏的特殊情况?
- 12. 是否有编译时func /宏来确定C++ 0x结构是否为POD?
- 13. 是否有LARGEST_INTEGER宏或类似的东西? (C)
- 14. Objective-C中的“函数”和“宏”是否有区别?
- 15. 是否有一个等价的AddRange为一个HashSet在C#
- 16. C++引用是否像宏替换一样工作?
- 17. 是否有C++
- 18. 是否有Eclipse的宏记录器?
- 19. 是否有宏检测操作系统...?
- 20. 是否有重写CPS的宏?
- 21. 是否有log4cplus的标准Autoconf宏?
- 22. Buck是否有平台名称宏?
- 23. Python类型()或__class__,==或者是
- 24. 是否有一个不需要C++运行时的SQLite C#库?
- 25. 是否有一个模拟的C++目标C财产
- 26. 是否有UWP一个HttpListener?
- 27. 是否有一个sql reindenter?
- 28. 是否VBA有一个Hash_HMAC
- 29. python AttributeError:类XXX没有属性'__class__'
- 30. 是否有可能禁用一些宏谷歌测试断言?
谢谢..这是一个好足够的日志 – mortal 2009-11-03 11:47:40
你要知道你的类首先要调用此;-) – 2009-11-03 11:48:18
这是记录,所以我知道我在哪里调用这个类。试图避免显式定义一个包含类名称的char数组 – mortal 2009-11-03 11:51:54