c++ - 不参与推导的模板参数包推为空的现行规则草案中的规范规则是什么?

标签 c++ templates language-lawyer

template<typename ...T, typename U>
void fun(U){}
int main(){
   fun(0);
}
这个片段代码被 GCC 和 Clang 接受。模板参数包T不参与函数调用上下文中的模板实参推导,遵循以下规则:
[temp.deduct.call]

Template argument deduction is done by comparing each function template parameter type (call it P) that contains template-parameters that participate in template argument deduction with the type of the corresponding argument of the call (call it A) as described below.


包装T包含在任何函数模板参数中。如果没有其他特殊规则规定,则扣除将根据以下情况失败:
[temp.deduct.type#2]

if any template argument remains neither deduced nor explicitly specified, template argument deduction fails.


但是,这种情况在现行标准中是由以下规则来裁定的,即:
[temp.arg.explicit#4]

A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced as an empty sequence of template arguments.


因此,上述情况可以认为成功推导了哪个离开包T带有一组空的模板参数。
但是,temp.arg.explicit#4 中的特殊规则已更改为当前草案中的注释
[temp.arg.explicit#note-1]

[Note 1: A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced as an empty sequence of template arguments. — end note]


所以,我想知道当前草案中是否有任何替代规范规则规定包 T不以其他方式推断将被推断为一组空的模板参数?

最佳答案

[temp.arg.explicit]/4 的先前规范部分

[...] A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced as an empty sequence of template arguments. [...]


作为 P1787R6 的一部分被制作成非规范性注释.
正如您所指出的,根据 [temp.deduct.type]/2 [ 重点 矿]:

Type deduction is done independently for each P/A pair [...], if any template argument remains neither deduced nor explicitly specified, template argument deduction fails.


[temp.arg.general]描述作为模板参数包的模板参数可能对应于零模板参数:

[...] When the parameter declared by the template is a template parameter pack, it will correspond to zero or more template-arguments.


[temp.variadic]/1明确提到模板参数包可以接受零参数:

A template parameter pack is a template parameter that accepts zero or more template arguments.


后跟一个非规范示例,该示例是基于参数包模板参数模板化的实体的空参数列表:
template<class ... Types> struct Tuple { };
Tuple<> t0;  // Types contains no arguments

现在,返回 [temp.arg.explicit]/4 :

If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list <> itself may also be omitted.


意思是Tuple上面的例子同样可以省略空参数列表
Tuple t0;  // Also OK: Types contains no arguments

但关键在于,根据上面的 [temp.arg.general],模板参数列表可能对应于零个参数,在这种情况下,不需要推导出模板参数。
如果你看看你自己的例子:
template<typename ...T, typename U>
void fun(U){}
int main(){
   fun(0);  // #1
}

你也可以调用 #1作为:
fun<>(0);  // argument list for parameter pack is empty
           // -> no argument (beyond that for `U`) to deduce
突出显示对应于模板参数 U 的可推论参数可以从显式模板参数中省略,而其余的模板参数则没有;即,作为模板形参包的模板形参的实参列表为空,因此没有剩余的模板形参需要推导。
因此

A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced as an empty sequence of template arguments.


是非规范/冗余的,解释了为什么它被包装成 [Note - [...] - end note]。

关于c++ - 不参与推导的模板参数包推为空的现行规则草案中的规范规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66773748/

相关文章:

c++ - vector 之间的转换

c - 设置指向在 C 中的局部范围内声明的变量的指针

c++ - 模板模板参数和 clang

c++ - `const` 作为移动构造函数的模板参数的效果

c++ - C++ 17 —将成员变量的类型映射到std::optionals

无符号整数加法可以调用未定义的行为吗?

sql - BigQuery 对 float 进行排序

c++ - 将 array.size() 与负值进行比较时出现 if 条件的意外行为

c++ - 模板类型转换问题

c++ - 我的多项式回归梯度下降有什么问题(C++,GNUPLOT)