有没有办法使用RTTI获取基于签名的typeinfo错位函数名称?

时间:2017-11-10 20:41:56

标签: c++ rtti typeid typeinfo

我想使用RTTI和错位函数(指针)类型字符串。

在将此分类为XY问题之前,我知道有更好的选项可以使用多态等来绑定函数。

这是一个纯粹的学术问题,如何正确使用typeid()函数指针,这些函数指针应该因其合法重载的签名而有所不同。

如果我使用following code,我似乎可以检索各种命名空间/类型的唯一typeinfo::name()值:

#include <iostream>
#include <typeinfo>
#include <string>

void foo(int) {
}

namespace woozle {
    void goozle(int) {}
}

struct bar {
    void baz(int) {}
    static void boo(int) {}
};

int main() {
    std::cout << typeid(&foo).name() << std::endl;
    std::cout << typeid(&woozle::goozle).name() << std::endl;
    std::cout << typeid(&bar::baz).name() << std::endl;
    std::cout << typeid(&bar::boo).name() << std::endl;
}

输出结果为:

PFviE
PFviE
M3barFviE
PFviE

完全符合我的预期(我假设错位名称中的i指的是参数签名。)

现在我想要这样的东西(这是完全合法的函数重载):

#include <iostream>
#include <typeinfo>
#include <string>

void foo(int) {
}

void foo(std::string) {
}

namespace woozle {
    void goozle(int) {}
    void goozle(std::string) {}
}

struct bar {
    void baz(int) {}
    static void boo(int) {}
    void baz(std::string) {}
    static void boo(std::string) {}
};

int main() {
    std::cout << typeid(&foo).name() << std::endl;
    std::cout << typeid(&woozle::goozle).name() << std::endl;
    std::cout << typeid(&bar::baz).name() << std::endl;
    std::cout << typeid(&bar::boo).name() << std::endl;
}

当然是compiler complains about ambiguity

main.cpp: In function 'int main()':
main.cpp:24:25: error: address of overloaded function with no contextual type information
     std::cout << typeid(&foo).name() << std::endl;
                         ^~~~
main.cpp:25:25: error: address of overloaded function with no contextual type information
     std::cout << typeid(&woozle::goozle).name() << std::endl;
                         ^~~~~~~
main.cpp:26:25: error: address of overloaded function with no contextual type information
     std::cout << typeid(&bar::baz).name() << std::endl;
                         ^~~~
main.cpp:27:25: error: address of overloaded function with no contextual type information
     std::cout << typeid(&bar::boo).name() << std::endl;
                         ^~~~

TL; DR

使用typeid()指定特定函数重载的正确语法是什么(如果有的话)?

如何提供错误消息所需的“上下文类型信息”

我是以深思维模式来自here

1 个答案:

答案 0 :(得分:6)

要从一组重载函数中选择特定函数,您可以使用强制转换符号:

std::cout << typeid(static_cast<void (*)(int)>(foo)).name() << std::endl;
std::cout << typeid(static_cast<void (*)(std::string)>(foo)).name() << std::endl;
std::cout << typeid(static_cast<void (bar::*)(int)>(&bar::baz)).name() << std::endl;
std::cout << typeid(static_cast<void (bar::*)(std::string)>(&bar::baz)).name() << std::endl;

特别是对于typeid,如果你已经写下了类型,你可以跳过实际的函数名。

std::cout << typeid(void (*)(int)).name() << std::endl;

更短,也可以完成工作。