为什么会出现错误"no matching function for call to 'A(A<...auto...>)'"?

Why is there an error "no matching function for call to 'A(A<...auto...>)'"?

在 C++20 中,我们有更好的 NTTP,它允许文字 class 类型:

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(主干))转储了一堆错误:

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>>{};
      |                ^~

我找到了一个解决方案,它为 A:

提供了一个明确的参数
template <typename T, A<T> x>
struct is_B<B<x>>{};

但是是多余的,无法解决在using中使用A时同样的错误:

template <A x>
using B_t = B<x>; // same error!!!

那么还有其他解决方案吗?

GCC 似乎不喜欢推导的 class 类型的占位符作为 NTTP,应该按照 [temp.param]/6(强调我的)接受:

A non-type template-parameter shall have one of the following (possibly cv-qualified) types:

  • a structural type (see below),
  • a type that contains a placeholder type ([dcl.spec.auto]), or
  • a placeholder for a deduced class type ([dcl.type.class.deduct]).

已经有相关的错误报告(PR96331,请参阅@TC 提供的示例)。