问题描述
在C ++ 20中,我们有更好的NTTP,它允许使用文字类类型:
template <typename T>
struct A{};
template <A> // note: it is a placeholder for NTTP A<T>
struct B{};
但是当我尝试专门针对B
的模板时:
template <typename>
struct is_B{};
template <A x>
struct is_B<B<x>>{}; // error!!!
编译器(GCC 10或GCC 11(trunk))转储了很多错误:
prog.cc:11:15: error: class template argument deduction Failed:
11 | struct is_B<B<x>>{};
| ^
prog.cc:11:15: error: no matching function for call to 'A(A<...auto...>)'
prog.cc:2:8: note: candidate: 'template<class T> A()-> A<T>'
2 | struct A{};
| ^
prog.cc:2:8: note: template argument deduction/substitution Failed:
prog.cc:11:15: note: candidate expects 0 arguments,1 provided
11 | struct is_B<B<x>>{};
| ^
prog.cc:2:8: note: candidate: 'template<class T> A(A<T>)-> A<T>'
2 | struct A{};
| ^
prog.cc:2:8: note: template argument deduction/substitution Failed:
prog.cc:11:15: note: mismatched types 'A<T>' and 'A<...auto...>'
11 | struct is_B<B<x>>{};
| ^
prog.cc:11:16: error: template argument 1 is invalid
11 | struct is_B<B<x>>{};
| ^~
template <typename T,A<T> x>
struct is_B<B<x>>{};
但这是多余的,并且在A
中使用using
时无法解决相同的错误:
template <A x>
using B_t = B<x>; // same error!!!
那么还有其他解决方法吗?
解决方法
GCC似乎不喜欢演绎类类型的占位符,如NTTP,应按照[temp.param]/6(强调我的观点)接受:
非类型模板参数应具有以下内容之一 (可能具有简历资格)类型:
- 一种结构类型(见下文)
- 包含占位符类型([dcl.spec.auto])的类型,或
- 推断类类型的占位符([dcl.type.class.deduct])。
已经有一个相关的错误报告(PR96331,请参阅@TC提供的示例)。