C++模板问题:如何从模板实参的模板实参中提取值?
解决方法:从模板实例中提取参数值A
咱们来拆解下你遇到的问题:
- 模板参数不匹配:你的
foo函数声明的是模板模板参数(template<auto A> class H),它需要传入的是像S这样的“模板本身”,但你调用时传的S<1>是已经实例化后的具体类,所以编译器找不到匹配的foo函数。 - 作用域问题:就算你传的是
S这个模板,foo里的A也不在当前作用域——A是H模板的参数,不是foo的参数,编译器根本不知道你说的A是啥。
下面给你两种可行的解决思路,都能让bar()正确返回1:
方案1:给S添加静态成员存储A
这是最直接的方式,把模板参数A存在S的静态常量里,这样任何实例化后的S<X>都能直接访问这个值:
template<auto A> struct S{ static constexpr auto value = A; // 把A存在静态成员中 }; // 现在foo接受具体的类型T(比如S<1>),直接返回T的value template<typename T> auto foo(){ return T::value; } auto bar(){ return foo<S<1>>(); // 现在会正确返回1 }
方案2:用模板特化提取A(不修改S的定义)
如果不想改动S的代码,可以通过模板特化来从S<1>这类实例中“挖”出模板参数A:
template<auto A> struct S{}; // 先定义一个模板工具类,用来提取S的模板参数 template<typename T> struct ExtractTemplateValue; // 对S<A>进行特化,提取出对应的A值 template<auto A> struct ExtractTemplateValue<S<A>>{ static constexpr auto value = A; }; // foo利用这个工具类获取值 template<typename T> auto foo(){ return ExtractTemplateValue<T>::value; } auto bar(){ return foo<S<1>>(); // 正确返回1 }
额外提示
如果你的编译器支持C++20及以上,还可以用更简洁的写法(比如consteval函数结合模板参数推导),但上面两种方法是兼容性更强的常规实现方式。
内容的提问来源于stack exchange,提问作者Leonardo Faria
相关产品推荐
相关产品推荐

