C++ 17可以推导出具有显式非类型参数的`auto`非类型`模板`参数模式匹配模板吗?

Vit*_*meo 10 c++ templates auto c++17

考虑这个例子(也可以在wandbox上使用):

template <template <auto> class>
void test() { }

template <int> 
struct X { };
Run Code Online (Sandbox Code Playgroud)

尝试test<X>()clang++4.0 (主干)上实例化会导致编译错误:

error: no matching function for call to 'test'
     test<X>();
     ^~~~~~~

note: candidate template ignored: 
      invalid explicitly-specified argument for 1st template parameter
void test() { }
Run Code Online (Sandbox Code Playgroud)

我最初的假设/直觉是test可以用来匹配任何template具有非类型参数的人.


但是,以下代码段成功编译:

template <template <auto> class>
void test() { }

//        vvvv
template <auto> 
struct X { };
Run Code Online (Sandbox Code Playgroud)

这是有意的吗?在P0127R2中找不到任何结论.

Bar*_*rry 9

这绝对是有意的.模板模板参数只能匹配采用相同类型参数的模板.这个:

template <template <auto> class>
void test() { }
Run Code Online (Sandbox Code Playgroud)

只能使用可以采用任何类型的非类型参数的类模板进行实例化.但是这个:

template <int> 
struct X { };
Run Code Online (Sandbox Code Playgroud)

不是这样的类模板.X只能用一个实例化int.它只是与模板模板参数的规范不匹配,因此错误.如果test想用指针类型实例化其类模板怎么办?或指向函数或指向成员的指针?那是不可能的.

你的第二次尝试,与template <auto> struct X { }; 匹配模板,模板参数,因此是良好的.另请注意,相反,testtemplate <int> class参数并传入template <auto> struct X { };也是格式良好的,因为参数比参数更通用.


相关措辞在[temp.arg.template]中:

模板参数的模板匹配模板的参数 P时中的每个模板参数的模板参数列表中的模板的参数的对应的类模板或别名模板A在相应的模板参数匹配模板参数列表P.两个模板参数匹配,如果它们是相同类型(类型,非类型,模板),非类型模板参数,它们的类型是等价的(14.5.6.1),对于模板模板参数,它们各自对应模板参数以递归方式匹配.


注意:等价措辞接受auto- autocase并拒绝auto- intcase,但似乎也拒绝int- autocase(基于我的阅读).我将尝试对其进行澄清.