【发布时间】:2018-02-01 13:56:45
【问题描述】:
我有一些代码可以处理许多指向不同签名函数的指针。这是一个sn-p:
#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>])();
}
有没有一种方法可以在没有大量开销和重新解释强制转换的情况下获得类似的结果?
【问题讨论】:
-
您绝对可以通过编写适当的提取方法来完成大部分工作来缩短它,但是完全摆脱花哨的演员表可能是不可能的。
-
想象有一个解决方案。编译器如何知道
function_map[key]()的返回类型而不自己指定呢?任何函数调用的返回类型必须在编译时知道,但在这种情况下,它将取决于key的值和function_map的状态,它们是运行时信息。在这种情况下,键恰好是从类型名称派生的。如果您更改示例,例如使用enum作为键,它可能会被清除。 -
你能改变函数声明还是固定的?否则,您可以反转方法并始终使用相同的声明。在这种情况下不再需要强制转换。
-
@VTT 我会很高兴只使用
static_cast。问题是,reinterpret_cast更难维护和捕获错误。 @FrançoisAndrieux 不幸的是,我不能使用枚举,我有不确定数量的用户定义类型。 -
@GuillaumeRacicot 是的,可能是this。 :-) ...好吧,我把它放在一个答案中。希望对你有帮助。
标签: c++ function-pointers reinterpret-cast