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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:50:14  来源:igfitidea点击:

Is there a __CLASS__ macro in C++?

c++macros

提问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 thispointer 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::functionnameuntil __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::Runwill then be

的输出Example::Run将是

Example: 0
Logger<Example>: 0