use*_*042 1 c++ rtti typeid typeinfo
我想使用RTTI和损坏的函数(指针)类型字符串.
在将其归类为XY问题之前,我知道有更好的选项可以使用多态等来绑定函数.
这是一个纯粹的学术问题,如何typeid()正确使用函数指针,这些函数指针应该因其合法重载的签名而有所不同.
如果我使用以下代码,似乎我可以检索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;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
Run Code Online (Sandbox Code Playgroud)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;
}
Run Code Online (Sandbox Code Playgroud)
当然编译器抱怨模棱两可:
Run Code Online (Sandbox Code Playgroud)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; ^~~~
指定特定函数重载的正确语法typeid()是什么(如果有的话)?
如何提供错误消息所需的"上下文类型信息"?
我是从深思熟虑的模式来到这里的.
要从一组重载函数中选择特定函数,您可以使用强制转换表示法:
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;
Run Code Online (Sandbox Code Playgroud)
特别是对于typeid,如果你已经写下了类型,你可以跳过实际的函数名.
std::cout << typeid(void (*)(int)).name() << std::endl;
Run Code Online (Sandbox Code Playgroud)
更短,也做得很好.