当部分专用化参数不使用其任何模板参数时,哪些规则适用
Which rules apply when an argument of partial specialization does not use any of its template parameters
N4567 [临时.class.规格匹配]P2
如果可以从实际模板参数列表 (14.8.2( 推导出部分专用化的模板参数,则部分专用化与给定的实际模板参数列表匹配。
template<class T, class U>
struct S{};
template<class U>
struct S<int, U>{};
S<char, int> s;
我知道部分专用化S<int, U>
与实际的模板参数列表不匹配char, int
,第二个参数U
可以从 14.8.2.5 int
但我不知道 14.8.2 中的哪些规则适用于第一个参数int
.
14.8.2.5 [温度扣除类型]p1
模板参数可以在几个不同的上下文中推导,但在每种情况下,根据模板参数指定的类型(称为
P
(与实际类型(调用它A
(进行比较,并尝试查找模板参数值(类型参数的类型、非类型参数的值、 或模板参数的模板(,在替换推导的值后,将产生P
(称为 推导A
(,兼容A
。
据我了解,S<int, U>
中的int
没有根据模板参数指定,因此 14.8.2.5 不适用。
想知道哪些规则处理这种情况,或者您可以纠正我关于 14.8.2.5
换句话说:直观地说,部分专业化S<int, U>
不匹配char,int
因为char
不匹配int
。
我想知道哪些规则确定char
与int
不匹配。
在我的理解中,S 中的 int 不是根据模板参数指定的,因此 14.8.2.5 不适用。
不,14.8.2.5
解释了如何推断类型,14.3
处理模板参数,您发布的代码失败14.3p1
:
14.3p1 ...模板 id 中指定的每个模板参数的类型和形式应与模板在其模板参数列表中声明的相应参数指定的类型和形式匹配。
template<class T, class U>
struct S<int, U> {};
// compiler error, template parameters not used in partial specialization
应该是
template<class U>
struct S<int, U> {};
所以
#1
template<class T, class U>
struct S{};
#2
template<class U>
struct S<int, U> {};
S<char, int> s; // uses #1
S<int, char> c; // uses #2 since S<int, U> matches more closely than S<T, U>
你提到gcc
拒绝了模板,而clang
接受了它。在我的测试中,VC++
和 gcc
默认给出一个编译器错误,并且根本没有编译代码,但是,clang
给出了一个警告,而是指出this partial specialization will never be used
并构建了二进制文件。因此,在所有情况下,它都会发出不符合项的通知,这只是默认情况下打开的编译器设置以及编译器实现如何处理不符合代码的问题。
希望能有所帮助。
在考虑这里发生的事情时:
template<class T, class U> struct S{}; // (1)
template<class U> struct S<int, U>{}; // (2)
S<char, int> s; // (1) or (2)?
为了确定我们用于s
的专业化,我们进入[temp.class.spec.match]:
当类模板在需要类实例化的上下文中使用时,有必要 确定是使用主模板还是使用部分模板之一生成实例化 专门化。这是通过将类模板专用化的模板参数与 模板参数列出了部分专用化。
在本例中,我们将<char, int>
与<int, U>
进行匹配。匹配是什么意思?
部分专用化与给定的实际模板参数列表匹配,如果 可以从实际模板参数列表 (14.8.2( 中推断出部分专用化。
基本上,我们正在推断U
以匹配int == char
和U == int
。等价地,我们正在考虑推断U
:
template <class U> void f(S<int, U> );
f(S<char, int>{} );
没有这样的扣除。
这导致我们:
— 如果未找到匹配项,则从主模板生成实例化。
这导致我们(1)
.
让我们举一个更有趣的案例:
S<int, char> s2;
现在,<int, char>
对阵<int, U>
的比赛,因为我们可以推断出U=char
。因此:
— 如果只找到一个匹配的专用化,则从该专用化生成实例化。
这导致我们(2)
.
- 模板模板参数:以下示例中应用了什么规则
- 自动参数捕获的扣除规则是什么?
- 函数参数绑定通过参考与传递指针传递数组的规则
- C++模板函数的默认参数的 ODR 规则
- 模板参数推导和表达式规则
- 参数包扣减有哪些规则
- 具有多个包的参数包匹配规则
- C++函数类型模板参数推导规则
- 哪些规则控制参数默认赋值?
- 可以对提升精神规则进行参数化
- 强制函数参数匹配某些规则
- 默认模板参数是否进入单定义规则
- 当部分专用化参数不使用其任何模板参数时,哪些规则适用
- 参数替换的C++规则
- 智能指针和参数列表分配规则
- 可变参数模板上下文中"..."令牌的规则是什么?
- 对"non-type"模板参数强制实施规则
- 解析器规则依赖于参数
- 为什么在推导模板参数时应用 §5/5?规则不能不同吗?
- Boost Spirit规则和语法中模板参数中的括号