【问题标题】:Is it possible to get the name of a function passed to a template?是否可以将函数的名称传递给模板?
【发布时间】:2019-06-20 16:27:13
【问题描述】:

我尝试在运行时获取传递给模板化类方法的类方法的名称。我想知道名称以便更好地跟踪输出。

这个问题源于我之前提出的问题: Templated wrapper method for other class methods

我尝试通过添加来获取名称

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!

是否可以获取传递函数的真实名称?

提前谢谢你!

【问题讨论】:

  • 您可以更改签名以接受另一个 char const* 参数作为第一个参数,并传入 C 字符串文字。我使用该技术作为事件的面包屑来找出它们的来源,这对于调试非常有用。
  • @Eljay 这就是我目前的做法,似乎没有其他选择:-/

标签: c++ templates rtti typeid


【解决方案1】:

没有。 typeid 仅对多态对象(即类类型的对象,具有虚函数)进行 RTTI。对于所有其他类型,它只会为您提供有关静态类型的信息,在本例中为函数指针类型。 (typeid 用于多态对象利用 vtable 来完成它的工作,但没有附加到函数的类似 vtable 的东西。)

对于此类调试/跟踪,您需要使用特定于平台的调试实用程序。

【讨论】:

  • 感谢您的解释。
    我还尝试显式初始化模板,例如:`template void B::foobarWrapper(void(A::*)(int)&& , int&&) ; ` 但是编译器说:` error C3190: 'void B::foobarWrapper(void (__thiscall A::* )(int) &&,int &&)' 提供的模板参数不是任何成员函数的显式实例化B' 错误 C2945:显式实例化不涉及模板类专业化 ` 你知道问题可能是什么吗?谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多