C++中如何根据整数值设置模板参数包类型?
实现方法
核心思路是通过模板元编程构造指定个数double参数、返回值为double的函数类型,再用该类型实例化std::function成员即可。
完整实现(C++14及以上,推荐写法)
利用std::index_sequence直接展开生成对应个数的double参数列表,逻辑简洁无递归,出错概率低:
#include <functional> #include <utility> // 辅助元函数:生成接收k个double参数、返回double的函数类型 template<unsigned k, typename Seq = std::make_index_sequence<k>> struct NDoubleFunc; template<unsigned k, size_t... Is> struct NDoubleFunc<k, std::index_sequence<Is...>> { // 展开参数包生成k个double形参 using type = double(decltype(static_cast<double>(Is))...); }; template<unsigned N> class Class { // 边界校验:N最小为1,保证_function2的参数个数N-1合法 static_assert(N >= 1, "Template parameter N must be greater than or equal to 1"); public: // N个double入参的函数对象 std::function<typename NDoubleFunc<N>::type> _function1; // N-1个double入参的函数对象 std::function<typename NDoubleFunc<N-1>::type> _function2; };
C++11兼容版本
如果编译环境不支持C++14的std::index_sequence,可以用递归模板实现相同的辅助元函数,替换上面的NDoubleFunc定义即可:
// C++11版本的辅助元函数 template<unsigned k> struct NDoubleFunc { private: template<typename... Args> static double(*deduce(Args...))(double, Args...); public: using type = typename std::remove_pointer< decltype(deduce(std::declval<typename NDoubleFunc<k-1>::type>())) >::type; }; template<> struct NDoubleFunc<0> { using type = double(); };
使用示例
#include <iostream> int main() { // N=2场景:_function1接2个double,_function2接1个double Class<2> obj2; obj2._function1 = [](double a, double b) { return a + b; }; obj2._function2 = [](double a) { return a * a; }; std::cout << obj2._function1(1.2, 3.8) << std::endl; // 输出5 std::cout << obj2._function2(4.0) << std::endl; // 输出16 // N=1边界场景:_function1接1个double,_function2无入参 Class<1> obj1; obj1._function1 = [](double a) { return a * 2; }; obj1._function2 = []() { return 3.14159; }; std::cout << obj1._function1(2.5) << std::endl; // 输出5 std::cout << obj1._function2() << std::endl; // 输出3.14159 return 0; }
类型校验说明
你可以通过静态断言验证生成的类型完全符合预期,比如:
#include <type_traits> // 验证N=3时的类型正确性 static_assert(std::is_same< decltype(Class<3>::_function1), std::function<double(double, double, double)> >::value, "_function1 type mismatch for N=3"); static_assert(std::is_same< decltype(Class<3>::_function2), std::function<double(double, double)> >::value, "_function2 type mismatch for N=3");
内容的提问来源于stack exchange,提问作者Артём Карпов
相关产品推荐
相关产品推荐

