C++ 有没有一种方法可以保存多种类型的指向函数的指针而无需重新解释?

C++ 有没有一种方法可以保存多种类型的指向函数的指针而无需重新解释?,c++,function-pointers,reinterpret-cast,C++,Function Pointers,Reinterpret Cast,我有一些代码,处理许多指向不同签名函数的指针。下面是一个片段: #include <unordered_map> // Simple type id system template<typename> void type_id(){} using type_id_t = void(*)(); // value type of our map. We reinterpret functions pointer to this type using held_type =

我有一些代码,处理许多指向不同签名函数的指针。下面是一个片段:

#include <unordered_map>

// Simple type id system
template<typename> void type_id(){}
using type_id_t = void(*)();

// value type of our map. We reinterpret functions pointer to this type
using held_type = void(*)();

// actual function type.
template<typename T>
using funct_type = T(*)();

int main() {
    std::unordered_map<type_id_t, held_type> function_map;

    function_map.emplace(type_id<int>, reinterpret_cast<held_type>(
        static_cast<func_type<int>>([]() -> int { return 42; });
    ));

    function_map.emplace(type_id<double>, reinterpret_cast<held_type>(
        static_cast<func_type<double>>([]() -> double { return 9.4; });
    ));

    // later on

    // prints 42
    std::cout << reinterpret_cast<func_type<int>>(function_map[type_id<int>])();

    // prints 9.4
    std::cout << reinterpret_cast<func_type<double>>(function_map[type_id<double>])();
}        
#包括
//简单类型id系统
模板无效类型_id(){}
使用类型_id_t=void(*)();
//我们地图的值类型。我们重新解释指向这种类型的函数指针
使用hold_type=void(*)();
//实际函数类型。
模板
使用functt_type=T(*)();
int main(){
std::无序映射函数映射;
功能映射安放(类型id,重新解释)(
静态_cast([]()->int{return 42;});
));
功能映射安放(类型id,重新解释)(
静态_cast([]()->double{return 9.4;});
));
//后来
//印刷品42

std::cout如果您可以稍微修改一下您的函数,您可以通过反转流程并删除返回类型来实现它。
以下是我的意思的一个例子:

#include <unordered_map>
#include <iostream>

template<typename T>
void call(T t, void *ptr) {
    *static_cast<T *>(ptr) = t;
}

// Simple type id system
template<typename> void type_id() {}
using type_id_t = void(*)();

// value type of our map. We reinterpret functions pointer to this type
using held_type = void(*)(void *);

// actual function type.
template<typename T>
using funct_type = T(*)();

int main() {
    std::unordered_map<type_id_t, held_type> function_map;

    function_map.emplace(type_id<int>, +[](void *ptr){ return call(42, ptr); });
    function_map.emplace(type_id<double>, +[](void *ptr) { call(9.4, ptr); });

    // prints 42
    int i;
    function_map[type_id<int>](&i);
    std::cout << i << std::endl;

    // prints 9.4
    double d;
    function_map[type_id<double>](&d);
    std::cout << d << std::endl;
}
#包括
#包括
模板
无效调用(T T,无效*ptr){
*静态_-cast(ptr)=t;
}
//简单类型id系统
模板无效类型_id(){}
使用类型_id_t=void(*)();
//映射的值类型。我们重新解释指向此类型的函数指针
使用hold_type=void(*)(void*);
//实际函数类型。
模板
使用functt_type=T(*)();
int main(){
std::无序映射函数映射;
函数_map.emplace(类型_id,+[](void*ptr){返回调用(42,ptr);});
函数_map.emplace(类型_id,+[](void*ptr){call(9.4,ptr);});
//印刷品42
int i;
函数映射[类型id](&i);

std::你可以通过编写一个合适的提取方法来完成大部分工作,从而使它变得更短吗?但是完全摆脱花哨的强制转换可能是不可能的。想象一下有一个解决方案。编译器如何知道
函数映射[key]()的返回类型
而不自己指定?任何函数调用的返回类型必须在编译时已知,但在这种情况下,它将取决于运行时信息
键的值和
函数映射的状态。在这种情况下,键恰好是从类型名派生的。如果更改例如,例如使用
枚举
作为键。您可以更改函数声明或这些声明是固定的吗?否则您可以反转方法并始终使用相同的声明。在这种情况下不再需要强制转换。@VTT我很乐意只使用
静态强制转换
。问题是,
重新解释强制转换
更难维护和捕获错误。@FrançoisAndrieux不幸的是,我不能使用枚举,我的用户定义类型数量不确定。@GuillaumeRacicot是的,可能是。:-…好的,我在回答。希望它能帮助你。