我希望创建一个std::type_index不需要RTTI的替代方案:
template <typename T>
int* type_id() {
static int x;
return &x;
}
Run Code Online (Sandbox Code Playgroud)
请注意,局部变量的地址x用作类型ID,而不是其x自身的值.另外,我不打算在现实中使用裸指针.我刚刚删除了与我的问题无关的所有内容.在这里查看我的实际type_index实现.
这种方法听起来是否合理,如果是这样,为什么?如果没有,为什么不呢?我觉得我在这里不稳定,所以我对我的方法将会或不会起作用的确切原因感兴趣.
典型的用例可能是在运行时注册例程以通过单个接口处理不同类型的对象:
class processor {
public:
template <typename T, typename Handler>
void register_handler(Handler handler) {
handlers[type_id<T>()] = [handler](void const* v) {
handler(*static_cast<T const*>(v));
};
}
template <typename T>
void process(T const& t) {
auto it = handlers.find(type_id<T>());
if (it != handlers.end()) {
it->second(&t);
} else {
throw std::runtime_error("handler not registered");
}
}
private:
std::map<int*, …Run Code Online (Sandbox Code Playgroud) 我使用函数指针的结构来实现不同后端的接口.签名非常不同,但返回值几乎都是void,void*或int.
struct my_interface {
void (*func_a)(int i);
void *(*func_b)(const char *bla);
...
int (*func_z)(char foo);
};
Run Code Online (Sandbox Code Playgroud)
但是后端不需要支持每个接口函数的功能.所以我有两种可能性,第一种选择是在每次调用之前检查指针是否为NULL.我不太喜欢这样,因为可读性和因为我担心性能影响(但我没有测量它).另一种选择是具有虚函数,对于极少数情况,接口函数不存在.
因此,我需要为每个签名都使用一个虚函数,我想知道是否有可能只有一个用于不同的返回值.并将其转换为给定的签名.
#include <stdio.h>
int nothing(void) {return 0;}
typedef int (*cb_t)(int);
int main(void)
{
cb_t func;
int i;
func = (cb_t) nothing;
i = func(1);
printf("%d\n", i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用gcc测试了这段代码,它确实有效.但它是否理智?或者它可以破坏堆栈还是会导致其他问题?
编辑:感谢所有答案,经过一番深入阅读后,我现在学到了很多关于调用约定的知识.并且现在可以更好地理解引擎盖下发生的事情.
我试图在c ++中创建一个非常开放的插件框架,在我看来,我已经想出了一个方法,但是一个唠叨的想法一直在告诉我,我正在做的事情非常非常错,它要么不起作用,要么会引起问题.
我对我的框架的设计包括一个调用每个插件init函数的内核.然后,init函数转向并使用内核registerPlugin并registerFunction获取唯一的id,然后分别使用该id注册插件想要访问的每个函数.
函数registerPlugin返回唯一的id.函数registerFunction接受id,函数名和泛型函数指针,如下所示:
bool registerFunction(int plugin_id, string function_name, plugin_function func){}
Run Code Online (Sandbox Code Playgroud)
其中plugin_function是
typedef void (*plugin_function)();
Run Code Online (Sandbox Code Playgroud)
然后内核获取函数指针并将其放在带有function_name和的映射中plugin_id.注册其功能的所有插件必须使函数类型化plugin_function.
为了检索函数,另一个插件调用内核
plugin_function getFunction(string plugin_name, string function_name);
Run Code Online (Sandbox Code Playgroud)
然后该插件必须将其plugin_function转换为其原始类型,以便可以使用它.它通过访问.h文件概述插件提供的所有功能,知道(理论上)正确的类型.插件由by实现为动态库.
这是完成允许不同插件相互连接的任务的聪明方法吗?或者这是一个疯狂而且非常可怕的编程技巧?如果是,请指出我正确的方向来实现这一目标.
编辑:如果需要澄清,请询问并提供.