C++中将模板函数作为模板参数时如何让示例代码成功编译
编译失败根因
原代码不符合C模板语法规则:C不支持直接将独立函数模板作为非类型模板参数传递。Test声明中写的template <template <class> void copy()>是非法的模板参数形式——模板模板参数仅能匹配类模板、别名模板,无法匹配函数模板,因此传入CopyVector、CopyVectorAsync时编译器无法完成参数匹配,直接报错。
修正方案
兼容C++11及以上标准的通用写法
将两个复制逻辑封装为带静态成员函数的类模板,适配模板模板参数的匹配规则,全版本编译器兼容,代码如下:
#include <vector> template <class T> struct CopyVector { static void exec() { std::vector<T> v; // 同步复制逻辑 } }; template <class T> struct CopyVectorAsync { static void exec() { std::vector<T> v; // 异步复制逻辑 } }; template <template <class> class CopyOp> void Test() { CopyOp<char>::exec(); CopyOp<short>::exec(); CopyOp<int>::exec(); } int main() { Test<CopyVector>(); Test<CopyVectorAsync>(); }
C++17及以上标准的简洁写法
如果编译环境支持C++17,可以借助泛型lambda、auto非类型模板参数特性,不需要修改原有函数模板的定义,写法更简洁:
#include <vector> template <class T> void CopyVector() { std::vector<T> v; /*...*/} template <class T> void CopyVectorAsync() { std::vector<T> v; /*...*/} template <auto copy_fn> void Test() { copy_fn.template operator()<char>(); copy_fn.template operator()<short>(); copy_fn.template operator()<int>(); } int main() { constexpr auto sync_copy = []<class T>() { CopyVector<T>(); }; constexpr auto async_copy = []<class T>() { CopyVectorAsync<T>(); }; Test<sync_copy>(); Test<async_copy>(); }
提示:C++17写法对编译器版本有要求,GCC 8+、Clang 9+、VS2019 16.3+才完整支持相关特性,需要兼容老环境时优先选择第一种类模板封装方案。
内容的提问来源于stack exchange,提问作者Alexey Starinsky
相关产品推荐
相关产品推荐

