Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a __CLASS__ macro in C++?

Tags:

c++

macros

People also ask

What is __ file __ in C?

__FILE__ This macro expands to the name of the current input file, in the form of a C string constant. This is the path by which the preprocessor opened the file, not the short name specified in ' #include ' or as the input file name argument. For example, "/usr/local/include/myheader.

What is __ LINE __ in C?

__LINE__ is a preprocessor macro that expands to current line number in the source file, as an integer. __LINE__ is useful when generating log statements, error messages intended for programmers, when throwing exceptions, or when writing debugging code.

How many types of macros are there in C?

Macro is defined by #define directive. There are two types of macros: Object-like Macros. Function-like Macros.

Are nested macros allowed in C?

The C preprocessor and macros are one of the most useful elements for writing portable C/C++ code . It even can be used to completely different purposes, like text processing. However, it suffers one major drawback: it does not support nested macros expansion (put differently, macros within macros).


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__)

The closest thing there's is to call typeid(your_class).name() - but this produces compiler specific mangled name.

To use it inside class just typeid(*this).name()


I would like to suggest boost::typeindex, which I learned about from Scott Meyer's "Effective Modern C++" Here's a basic example:

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

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


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


I think using __PRETTY_FUNCTION__ is good enough though it includes namespace as well i.e. namespace::classname::functionname until __CLASS__ is available.


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


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).