如何在不修改enumerate函数模板的前提下处理多类型传入参数?
问题描述
在开发C++代码时,需要向enumerate模板函数传入一个可调用对象,使其能处理不同类型的参数(如vector<int>和int),但无法修改enumerate函数的实现。当前定义的模板函数func存在编译器无法推导模板参数的问题,相关代码如下:
enumerate函数实现:
template <typename F> void enumerate(F &func) noexcept(false) { vector<int> a{1, 2, 3, 4}; int b = 10; func(a); func(b); }
完整测试代码:
#include <iostream> #include <vector> using namespace std; template <typename T> void func(const T &data) { cout << "hello " << typeid(T).name() << endl; } template <typename F> void enumerate(F &func) noexcept(false) { vector<int> a{1, 2, 3, 4}; int b = 10; func(a); func(b); } int main() { enumerate(func); // 编译错误:无法推导模板参数F return 0; }
可行解决方案
方法1:使用泛型Lambda(C++14及以上)
泛型Lambda的参数支持自动类型推导,可直接作为可调用对象传入enumerate,无需单独定义模板函数:
#include <iostream> #include <vector> using namespace std; template <typename F> void enumerate(F &func) noexcept(false) { vector<int> a{1, 2, 3, 4}; int b = 10; func(a); func(b); } int main() { auto func = [](const auto &data) { cout << "hello " << typeid(decltype(data)).name() << endl; }; enumerate(func); return 0; }
方法2:使用仿函数(类类型可调用对象)
定义一个包含模板operator()的类,类的实例可以接受任意类型的参数,完美适配enumerate的多类型调用需求:
#include <iostream> #include <vector> using namespace std; struct Func { template <typename T> void operator()(const T &data) const { cout << "hello " << typeid(T).name() << endl; } }; template <typename F> void enumerate(F &func) noexcept(false) { vector<int> a{1, 2, 3, 4}; int b = 10; func(a); func(b); } int main() { Func func; enumerate(func); return 0; }
方法3:包装重载函数集(兼容性方案)
如果必须基于原有func模板函数改造,可以通过定义一个包含重载operator()的结构体,将不同类型的func实例包装进去:
#include <iostream> #include <vector> using namespace std; template <typename T> void func(const T &data) { cout << "hello " << typeid(T).name() << endl; } template <typename F> void enumerate(F &func) noexcept(false) { vector<int> a{1, 2, 3, 4}; int b = 10; func(a); func(b); } struct FuncWrapper { void operator()(const vector<int>& v) { func(v); } void operator()(int x) { func(x); } }; int main() { FuncWrapper wrapper; enumerate(wrapper); return 0; }
内容的提问来源于stack exchange,提问作者킵고잉
相关产品推荐
相关产品推荐

