【问题标题】:Was the C++14 standard defective/underspecified w.r.t. deduction of an array type function parameter from an initializer list?C++14 标准是否有缺陷/未指定 w.r.t.从初始值设定项列表中扣除数组类型函数参数?
【发布时间】:2021-11-04 05:43:55
【问题描述】:

下面的程序也就不足为奇了

// #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

给定类型P 可以由许多其他类型组成, 模板和非类型值:

  • [...]
  • /3.4 数组类型包括数组元素类型和数组绑定的值。

通过以下示例解释为什么演绎成功:

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

一个函数参数,其关联参数是一个初始化列表 ([dcl.init.list]),但该参数没有 std::initializer_list 或对可能有 cv 限定的 std::initializer_list 类型的引用。

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

从 C++17 标准和更高版本开始,[temp.deduct.call]/1 已更新为表示可以从(非空)初始化列表中推导出数组类型参数,但是这个 was not present in the C++14 standard[temp.deduct.type]/5.6,关于非推导上下文,明确引用 [temp.deduct.call]/1 以获取规则的例外情况。

这是 C++14 标准的缺陷/规范不足吗?

  • 如果有,是否有相关的缺陷报告(1)
  • 如果不是,C++14 标准的哪些段落涵盖了上述#1 的格式正确?

(1) 我自己找了一个,没有成功。

【问题讨论】:

标签: c++ c++14 language-lawyer template-argument-deduction


【解决方案1】:

这是DR 1591

这似乎是合理的......允许一个数组绑定 从初始化列表中的元素数推导出来,例如,

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

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


注意:好像是Language Lawyerbeat me to it,但我是通过git blamegit blame 独立发现的:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-17
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 1970-01-01
    相关资源
    最近更新 更多