Is there a __CLASS__ macro in C++?

2019-01-03 22:57发布

Is there a __CLASS__ macro in C++ which gives the class name similar to __FUNCTION__ macro which gives the function name

标签: c++ macros
14条回答
倾城 Initia
2楼-- · 2019-01-03 23:30

If you need something that will actually produce the class name at compile time, you can use C++11 to do this:

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

template<class T> T& classMacroImpl(const T* t);

I recognize that this is not the same thing as __FUNCTION__ but I found this post while looking for an answer like this. :D

查看更多
一夜七次
3楼-- · 2019-01-03 23:32

This works quite nicely if you are willing to pay the cost of a pointer.

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__ ) {};
};
查看更多
爷、活的狠高调
4楼-- · 2019-01-03 23:33

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.

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.

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__)
查看更多
Fickle 薄情
5楼-- · 2019-01-03 23:34

Not yet. (I think __class__ is proposed somewhere). You can also try to extract class part from __PRETTY_FUNCTION__.

查看更多
我只想做你的唯一
6楼-- · 2019-01-03 23:34

You can get the function name including class name. This can process C-type funcitons.

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) + "()";
}
查看更多
祖国的老花朵
7楼-- · 2019-01-03 23:37

Works with msvc and gcc too

#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
查看更多
登录 后发表回答