首页 > 解决方案 > 何时提供默认参数作为模板参数

问题描述

template<typename T, typename U = T>
struct Test{};
template<typename T>
void func(Test<T>){  //#1
}
int main(){
  func(Test<int>{});  //#2
}

标准中似乎没有任何规则提到模板参数需要默认参数的情况。

dcl.fct.default#1

如果在参数声明中指定了初始化子句,则此初始化子句用作默认参数。默认参数将在缺少尾随参数的调用中使用。

在本节中,该规则明确描述了何时为函数调用提供默认参数。但是,我没有在标准中找到与上面描述何时将默认参数作为模板参数提供的句子类似的引用。

比如Test<T>#1。也许在#1,专业化是Test<T,T>,这只是推理。但是,标准中没有正式的术语明确描述这一点。

将默认参数作为模板参数的唯一引用在以下规则中:
temp#arg-8

当 simple-template-id 没有命名函数时,默认模板参数在需要该默认参数的值时被隐式实例化。[ 示例:
模板<typename T, typename U = int> struct S { };
S<布尔>* p; // p 的类型是 S<bool, int>*
U 的默认参数被实例化为类型S<bool, int>*。—结束示例]

考虑代码 at #1,默认参数是否需要 at #1?如果是(这时候似乎需要,因为如果我没有为模板参数U指定默认参数,那么此时#1会出现错误。见godbolt结果),根据上面的引用,默认模板-argument 需要被隐式实例化,但是此时,T是一个模板参数,并且这样的函数模板的定义什么都不实例化(此时它只是一个函数模板定义)。那么,这句话是如何解释的呢?

标签: c++language-lawyer

解决方案


There is also this paragraph inside [temp.names]:

A template-id is valid if

  • there is an argument for each non-deducible non-pack parameter that does not have a default template-argument,

So one could consider that a default-argument is needed means a default-argument is needed in order to make the template-id valid and that when there lacks a template argument, the argument is the default argument value. But I have not found anything explicit in the standard for class templates. For function template this is more explicit. Probably nobody pointed out this hole in the standard because this is a common pattern: default is used in place of what is not user provided. Maybe it will not be changed because the definition of default in the english dictionary is already given:

IT. the way that something will happen or appear automatically, especially on a computer, if you do not make any different choices -- cambrige online dictionary


推荐阅读