C++如何通过config模板类型推导函数参数类型与编译期常量
解决方案
你要的写法完全可以实现,核心是要么给config结构体导出内部的类型和常量别名,要么通过类型萃取从config实例中提取对应的参数,同时注意C++中依赖模板参数的类型需要加typename关键字修饰。
方法1:修改config结构体导出内部类型与常量
这是最简洁的方案,直接在config定义中对外暴露你需要用到的模板参数:
#include <array> template <typename T, int Size> struct config { // 导出模板参数别名 using type = T; static constexpr int size = Size; T field; /* various other things */ }; // 你的目标写法,只需要一个模板参数 template <typename C> // 注意:依赖模板参数的类型必须加typename关键字,否则编译器无法识别这是类型 void func(C arg0, typename C::type arg1, std::array<int, C::size> &arg2) { int i = C::size; arg0.field = arg1; }
使用示例:
int main() { config<int, 5> cfg; std::array<int,5> arr; func(cfg, 10, arr); // 自动推导模板参数,无需显式指定 return 0; }
方法2:使用类型萃取(无需修改原有config定义)
如果你不能改动原有config的定义,可以额外写一个类型萃取模板来提取参数:
#include <array> // 原有未修改的config定义 template <typename T, int Size> struct config { T field; /* various other things */ }; // 类型萃取模板,用于从config实例中提取参数 template <typename C> struct config_traits; // 偏特化匹配所有config实例 template <typename T, int Size> struct config_traits<config<T, Size>> { using type = T; static constexpr int size = Size; }; // 函数实现 template <typename C> void func(C arg0, typename config_traits<C>::type arg1, std::array<int, config_traits<C>::size> &arg2) { int i = config_traits<C>::size; }
C++20 额外优化:加概念约束避免非法类型传入
如果使用C++20及以上版本,可以加概念约束,保证传入的C一定是config的实例,避免传错类型时编译器报错信息不友好:
template <typename C> concept is_config = requires { typename config_traits<C>::type; requires std::is_same_v<C, config<typename config_traits<C>::type, config_traits<C>::size>>; }; // 用概念约束模板参数 template <is_config C> void func(C arg0, typename config_traits<C>::type arg1, std::array<int, config_traits<C>::size> &arg2) { int i = config_traits<C>::size; }
内容的提问来源于stack exchange,提问作者Frogblast
相关产品推荐
相关产品推荐

