Search code examples
c++templatesrttitypeid

Is it possible to get the name of a function passed to a template?


I try to get the name of a class method on runtime which is passed to a templated class method. I would like to know the name for better trace output.

The question results from the question that I asked before: Templated wrapper method for other class methods

I tried to get the name by adding

typeid(func).name()

But the result is not really satisfying because the name of the function is always printed as a *, see the examples below.

I also tried different compilers (msvc, gcc) and demangle options (abi::__cxa_demangle), but the result is always more or less the same.

#include <algorithm>
#include <functional>
#include <iostream>

class A
{
public:
    void foo(int x) {
        std::cout << "Foo: " << x << std::endl;
    }

    void bar(int x, float y) {
        std::cout << "Bar: " << x << ", " << y << std::endl;
    }
};

class B
{
public:
    void fooAndMore(int x) {
        foobarWrapper(&A::foo, x);
    }

    void barAndMore(int x, float y) {
        foobarWrapper(&A::bar, x, y);
    }

    template<typename  T, typename... Args>
    void foobarWrapper(T func, Args&&... args)
    {
        std::cout << "Start!" << std::endl;

        auto funcName = typeid(func).name();
        std::cout << "Functionname: " << funcName << std::endl;

        auto caller = std::mem_fn( func);
        caller( A(), args...);

        std::cout << "End!" << std::endl;
    }
};

int main()
{
    B b;
    b.fooAndMore(1);
    b.barAndMore(2, 3.5f);
}

I expected something like that:

Start!
Functionname: void (__thiscall A::foo)(int)
Foo: 1
End!
Start!
Functionname: void (__thiscall A::bar)(int,float)
Bar: 2, 3.5
End!

Actual results:

Start!
Functionname: void (__thiscall A::*)(int)
Foo: 1
End!
Start!
Functionname: void (__thiscall A::*)(int,float)
Bar: 2, 3.5
End!

Is it possible to get the real name of the passed function?

Thank you in advance!


Solution

  • No. typeid only does RTTI for polymorphic objects (i.e. objects of class type, with virtual functions). For all other types, it'll just give you information about the static type, in this case a function pointer type. (typeid for polymorphic objects leverages the vtable to do its work, but there's no vtable-like thing attached to functions.)

    For debugging/tracing of this sort, you'll need to use platform-specific debugging utilities.