有没有办法使用 RTTI 获取基于签名的类型信息损坏的函数名称?
Is there a way to get a signature based typeinfo mangled function name using RTTI?
我想使用 RTTI 和错位函数(指针)类型的字符串。
在您将其归类为 XY 问题之前,我知道有更好的选项可以使用多态性等来绑定函数。
这是一个纯粹的学术问题,如何正确使用 typeid()
函数指针,函数指针的合法重载签名应该有所不同。
如果我使用 following code,似乎我可以检索各种 namespaces/types:
的唯一 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 的深度思考模式。
到 select 您可以使用的一组重载函数中的特定函数使用强制转换符号:
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;
更短,也能胜任这项工作。
我想使用 RTTI 和错位函数(指针)类型的字符串。
在您将其归类为 XY 问题之前,我知道有更好的选项可以使用多态性等来绑定函数。
这是一个纯粹的学术问题,如何正确使用 typeid()
函数指针,函数指针的合法重载签名应该有所不同。
如果我使用 following code,似乎我可以检索各种 namespaces/types:
的唯一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 的深度思考模式。
到 select 您可以使用的一组重载函数中的特定函数使用强制转换符号:
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;
更短,也能胜任这项工作。