C++ 中有 __CLASS__ 宏吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1666802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a __CLASS__ macro in C++?
提问by mortal
Is there a __CLASS__
macro in C++ which gives the class name similar to __FUNCTION__
macro which gives the function name
__CLASS__
C++中是否有一个宏,它给出的类名类似于__FUNCTION__
给出函数名的宏
采纳答案by Aleksei Potov
The closest thing there's is to call typeid(your_class).name()
- but this produces compiler specific mangled name.
最接近的是调用typeid(your_class).name()
- 但这会产生编译器特定的损坏名称。
To use it inside class just typeid(*this).name()
在课堂上使用它只是 typeid(*this).name()
回答by Andrew Prock
The problem with using typeid(*this).name()
is that there is no this
pointer in a static method call. The macro __PRETTY_FUNCTION__
reports a class name in static functions as well as method calls. However, this will only work with gcc.
using 的问题typeid(*this).name()
在于this
静态方法调用中没有指针。该宏__PRETTY_FUNCTION__
报告静态函数和方法调用中的类名。但是,这只适用于 gcc。
Here's an example of extracting the 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 macro __METHOD_NAME__
will return a string of the form <class>::<method>()
, trimming the return type, modifiers and arguments from what __PRETTY_FUNCTION__
gives you.
宏__METHOD_NAME__
将返回一个形式为 的字符串,<class>::<method>()
从__PRETTY_FUNCTION__
给你的内容中修剪返回类型、修饰符和参数。
For something which extracts just the class name, some care must be taken to trap 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__)
回答by Spacemoose
I would like to suggest boost::typeindex, which I learned about from Scott Meyer's "Effective Modern C++" Here's a basic example:
我想推荐boost::typeindex,这是我从 Scott Meyer 的“Effective Modern C++”中了解到的,这是一个基本示例:
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'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";
}
Compiled with "g++ --std=c++14" this produces the following
用“g++ --std=c++14”编译这会产生以下结果
Output
输出
If you want to print a template type, that's easy.
T = double
To get it from an object instance, just use decltype:
fb's type is : foo_bar
如果您想打印模板类型,那很容易。
T = 双倍
要从对象实例中获取它,只需使用 decltype:
fb 的类型是: foo_bar
回答by Michael Krelin - hacker
Not yet. (I think __class__
is proposed somewhere). You can also try to extract class part from __PRETTY_FUNCTION__
.
还没有。(我认为__class__
是在某处提出的)。您也可以尝试从__PRETTY_FUNCTION__
.
回答by vaibhav
I think using __PRETTY_FUNCTION__
is good enough though it includes namespace as well i.e. namespace::classname::functionname
until __CLASS__
is available.
我认为 using__PRETTY_FUNCTION__
已经足够好了,尽管它也包含命名空间,即namespace::classname::functionname
直到__CLASS__
可用。
回答by ndim
If your compiler happens to be g++
and you are asking for __CLASS__
because you want a way to get the current method name including the class, __PRETTY_FUNCTION__
should help (according to info gcc
, section 5.43 Function Names as Strings).
如果您的编译器恰好是g++
并且您要求是__CLASS__
因为您想要一种获取当前方法名称(包括类)的方法,那么__PRETTY_FUNCTION__
应该会有所帮助(根据5.43info gcc
节函数名称作为字符串)。
回答by Charles.Lee
You can get the function name including class name. This can process C-type funcitons.
您可以获得包括类名的函数名。这可以处理 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) + "()";
}
回答by Ruben Bartelink
If you're talking MS C++ (You should state, esp as __FUNCTION__
is a non-standard extension), there are __FUNCDNAME__
and __FUNCSIG__
symbolswhich you could parse
如果你在谈论MS C ++(应该说明,尤指__FUNCTION__
是一种非标准的扩展名),有__FUNCDNAME__
和__FUNCSIG__
符号,你可以解析
回答by Andrey Epifantsev
My solution:
我的解决方案:
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 works for Visual C++ 12.
我为 Visual C++ 12 工作。
回答by Sven Vranckx
Here's a solution based on the __FUNCTION__
macro and C++ templates:
这是基于__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();
}
Here's an example of how this could be used for a 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 output of Example::Run
will then be
的输出Example::Run
将是
Example: 0
Logger<Example>: 0