如何在C++中将不同类型函数作为模板参数,扩展多类型调用模板?
实现可指定模板函数的
call_for_multi_type 原代码中的call_for_multi_type固定调用模板函数f,现在需要扩展该函数,使其能在编译阶段指定不同的模板函数(如func1、func2),调用方式调整为:
call_for_multi_type<func1, Ops::AND, int, double, float>(1) call_for_multi_type<func2, Ops::AND, int, double, float>(1)
解决方案
通过模板模板参数(template template parameter)实现将模板函数作为模板参数传递,修改call_for_multi_type的模板参数列表,将目标模板函数作为第一个参数传入,后续替换原函数中对f的调用为传入的模板函数。
完整代码示例
#include <iostream> #include <ostream> // 定义多个不同的模板函数 template <typename T> bool func1(int) { __builtin_unreachable(); } template <> bool func1<int>(int) { return true; } template <> bool func1<float>(int) { return true; } template <> bool func1<double>(int) { return false; } template <typename T> bool func2(int) { __builtin_unreachable(); } template <> bool func2<int>(int) { return false; } template <> bool func2<float>(int) { return false; } template <> bool func2<double>(int) { return true; } enum class Ops { OR, AND, VOID }; // 修改后的call_for_multi_type,新增模板模板参数Func template<template<typename> typename Func, Ops Op, typename T, typename... Ts> bool call_for_multi_type(int arg) { if constexpr (sizeof...(Ts) == 0) { return Func<T>(arg); // 替换原f<T>为Func<T> } else { if constexpr (Op == Ops::OR) { return Func<T>(arg) || call_for_multi_type<Func, Op, Ts...>(arg); } else if constexpr (Op == Ops::AND) { return Func<T>(arg) && call_for_multi_type<Func, Op, Ts...>(arg); } else if constexpr (Op == Ops::VOID) { return (Func<T>(arg), call_for_multi_type<Func, Op, Ts...>(arg)); } else { __builtin_unreachable(); } } } int main() { // 调用不同模板函数的示例 std::cout << call_for_multi_type<func1, Ops::AND, int, double, float>(1) << '\n'; // 输出0 std::cout << call_for_multi_type<func1, Ops::OR, int, float, double>(1) << '\n'; // 输出1 std::cout << call_for_multi_type<func2, Ops::AND, int, double, float>(1) << '\n'; // 输出0 std::cout << call_for_multi_type<func2, Ops::OR, int, float, double>(1) << '\n'; // 输出1 return 0; }
关键点说明
- 模板模板参数
template<typename> typename Func用于接收符合template<typename T> bool(int)签名的模板函数,确保传入的函数能被正确实例化调用。 - 若需支持不同签名的模板函数(如参数/返回值类型不同),可使用C++20的
auto模板参数配合概念约束,或把函数包装成仿函数传入:// 仿函数示例 struct Func3 { template<typename T> int operator()(char arg) { return static_cast<int>(arg); } }; // 适配仿函数的call_for_multi_type版本 template<typename Func, Ops Op, typename T, typename... Ts> auto call_for_multi_type(auto arg) { if constexpr (sizeof...(Ts) == 0) { return Func{}.template operator()<T>(arg); } else { // 对应逻辑调整... } }
内容的提问来源于stack exchange,提问作者zclll
相关产品推荐
相关产品推荐

