为什么会出现错误“没有匹配的函数来调用'AA <... auto ...>'”?

问题描述

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

我找到了一个解决方案,该解决方案为A提供了明确的参数:

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提供的示例)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...