【发布时间】: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 标准似乎不支持这一点,尤其是 T 和 N 可以从初始化列表参数推导出来?
给定类型
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) 我自己找了一个,没有成功。
【问题讨论】:
-
@LanguageLawyer 就是这样,谢谢!您想提供答案吗?
标签: c++ c++14 language-lawyer template-argument-deduction