Можно ли получить имя функции, переданной в шаблон? - PullRequest
3 голосов
/ 20 июня 2019

Я пытаюсь получить имя метода класса во время выполнения, которое передается шаблонному методу класса. Я хотел бы знать имя для лучшего вывода трассировки.

Вопрос вытекает из вопроса, который я задавал ранее: Шаблонный метод-оболочка для других методов класса

Я попытался получить имя, добавив

typeid(func).name()

Но результат не совсем удовлетворительный, потому что имя функции всегда печатается как *, см. Примеры ниже.

Я также пробовал разные компиляторы (msvc, gcc) и параметры demangle (abi :: __ cxa_demangle), но результат всегда более или менее одинаков.

#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);
}

Я ожидал что-то подобное:

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

Фактические результаты:

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

Можно ли получить реальное имя переданной функции?

Заранее спасибо!

1 Ответ

2 голосов
/ 20 июня 2019

Нет. typeid делает RTTI только для полиморфных объектов (то есть объектов типа класса с виртуальными функциями). Для всех других типов это просто даст вам информацию о статическом типе, в данном случае тип указателя на функцию. (typeid для полиморфных объектов использует vtable для своей работы, но к функциям не прикрепляется vtable-подобная вещь.)

Для такого рода отладки / трассировки вам понадобятся утилиты отладки для конкретной платформы.

...