C++中是否有__CLASS__宏?

mor*_*tal 89 c++ macros

__CLASS__C++中是否有一个宏,它给出类似于__FUNCTION__宏的类名,它给出了函数名

And*_*ock 66

使用的问题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__)
Run Code Online (Sandbox Code Playgroud)

__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__)
Run Code Online (Sandbox Code Playgroud)

  • 你不应该用`#ifdef __GNU_C__`包围这个吗? (4认同)
  • 我宁愿使用 find_last_of("::") 否则该函数只会返回一个命名空间(如果有) (2认同)

Ale*_*tov 61

最接近的是调用typeid(your_class).name()- 但这会产生编译器特定的受损名称.

要在课堂内使用它 typeid(*this).name()

  • @kexik:预处理器也不知道函数,标准`__func__`和非标准`__FUNCTION__`不是宏.微软将`__FUNCTION__`作为一个宏来记录,但它并不是真的,当你使用`/ P`进行编译时,它不会被预处理器扩展. (5认同)
  • 遗憾的是它没有定义为__ CLASS __,它在预处理器阶段可以很方便!:( (3认同)
  • typeid(*this).name()可以在类函数中使用 (2认同)
  • 那更好.至于知道类,定义char数组声音比推迟到运行时更好. (2认同)
  • @Max它不会,但可以.它对功能的了解方式类似:-P (2认同)

Mic*_*ker 9

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


Spa*_*ose 9

我想建议我从Scott Meyer的"Effective Modern C++"中学到的boost :: typeindex这是一个基本的例子:

#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";
}
Run Code Online (Sandbox Code Playgroud)

用"g ++ --std = c ++ 14"编译,产生以下结果

产量

如果要打印模板类型,那很容易.

T =双倍

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

fb的类型是:foo_bar


小智 7

我认为使用__PRETTY_FUNCTION__虽然它包括命名空间,但是namespace::classname::functionname直到__CLASS__可用时已经足够好了.


Jon*_*son 7

如果您需要在编译时实际生成类名的东西,您可以使用 C++11 来做到这一点:

#define __CLASS__ std::remove_reference<decltype(classMacroImpl(this))>::type

template<class T> T& classMacroImpl(const T* t);
Run Code Online (Sandbox Code Playgroud)

我意识到这与__FUNCTION__我在寻找这样的答案时发现了这篇文章不同。:D

  • 它只获取类的类型,而不是字符串表示形式 (7认同)

dar*_*gon 6

__PRETTY_FUNCTION__我使用constexprC++17方法创建了一个函数constexpr std::string_view。我还对算法进行了一些更新,使其更加可靠(感谢@n.'pronouns' m在64387023中的帮助)。

constexpr std::string_view method_name(const char* s)
{
    std::string_view prettyFunction(s);
    size_t bracket = prettyFunction.rfind("(");
    size_t space = prettyFunction.rfind(" ", bracket) + 1;
    return prettyFunction.substr(space, bracket-space);
}
#define __METHOD_NAME__ method_name(__PRETTY_FUNCTION__)
Run Code Online (Sandbox Code Playgroud)

在 C++20 中,可以将函数声明为consteval强制它在编译时求值。此外,还有std::basic_fixed_string用作模板参数