是 C++14 标准 defective/underspecified w.r.t。从初始化列表中推导数组类型函数参数?

Was the C++14 standard defective/underspecified w.r.t. deduction of an array type function parameter from an initializer list?

毫不奇怪,下面的程序

// #1
template<typename T, std::size_t N>
void f(T (&&)[N]) {}

int main() { f({1,2,3}); }

在 C++14 中看起来格式良好(好吧,至少我尝试过的所有编译器似乎都接受它)。

但是,这似乎不受 C++14 标准的支持,特别是 TN 可以从初始化列表参数中推导出来吗?

[temp.deduct.type]/3.4

A given type P can be composed from a number of other types, templates, and non-type values:

  • [...]
  • /3.4 An array type includes the array element type and the value of the array bound.

解释为什么推导成功的例子如下:

template<typename T, std::size_t N>
void f(T (&)[N]) {}

int main() { 
    int arr[] = {1, 2, 3};  // #2
    f(arr);
}

特别是 [dcl.init.aggr]/4 管理 #2 声明和大小为 3 的数组(即使声明中的类型被省略)。

但是,在函数调用的上下文中,根据 [temp.deduct.type]/5.6

A function parameter for which the associated argument is an initializer list ([dcl.init.list]) but the parameter does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list type.

...这是一个非推导的上下文。

从 C++17 标准及以后的标准 [temp.deduct.call]/1 has been updated to express that an array type argument can be deduced from a (non-empty) initializer list, but this was not present in the C++14 standard, and [temp.deduct.type]/5.6,关于非推导上下文,明确引用 [temp.deduct.call]/1 以获取规则的例外情况。

这是 C++14 标准的 defect/underspecification 吗?

(1) 自己找了一个都没成功

这是DR 1591

It would seem reasonable ... to allow an array bound to be deduced from the number of elements in the initializer list, e.g.,

  template<int N> void g(int const (&)[N]);
  void f() {
    g( { 1, 2, 3, 4 } );
  }

作为 DR,它追溯适用于 C++14。


注意:似乎 Language Lawyer , but I found it independently through git blametemplates.tex:)