如何实现编译期将ID转变量的可变参数函数以调用目标函数?
解决方案
要实现callIndirectly,核心是利用编译期常量参数传递ID——因为componentForId需要模板参数(必须编译期确定)。具体实现步骤如下:
- 把
callIndirectly的模板参数改为非类型模板参数,直接接收CID枚举值,确保每个ID都是编译期可确定的常量。 - 在函数内部展开参数包,对每个ID调用
componentForId<id>(),再将结果传递给someFunction。
修改后的完整代码:
#include <cstdint> enum CID { A, B }; struct ComponentA{}; struct ComponentB{}; ComponentA ca; ComponentB cb; template <uint32_t id> constexpr auto & componentForId() { if constexpr (id == A) return ca; if constexpr (id == B) return cb; } void someFunction(ComponentA&, ComponentB&) {} // 用非类型模板参数接收CID枚举值 template <CID... ids> void callIndirectly() { // 展开参数包,将每个ID传入componentForId模板 someFunction(componentForId<ids>()...); } int main() { someFunction(ca, cb); someFunction(componentForId<A>(), componentForId<B>()); // 调用时将ID作为模板参数传入 callIndirectly<A, B>(); }
关键说明
- 原设想的
callIndirectly(A, B)是传递运行时参数,但componentForId要求模板参数必须编译期确定,因此必须改为模板参数传递的形式(callIndirectly<A, B>()),这是C++模板机制的硬性要求。 - 如果传入的ID数量、类型与
someFunction的参数不匹配,编译器会直接报错,天然保证类型安全。
内容的提问来源于stack exchange,提问作者Harald H
相关产品推荐
相关产品推荐

