在阅读不同主题时,我遇到了一种奇怪的行为,至少对我来说是这样。
这整个想法源于 auto
之间的特殊互动。和大括号。如果你写这样的东西:
auto A = { 1, 2, 3 }
编译器会推导出 A
成为 std::initializer_list
.奇怪的是,类似的规则不仅适用于 auto
。 ,那里可能有特殊的原因呢,也可能是其他的事情。
如果你写如下:
template<typename T>
void f(std::vector<T> Vector)
{
// do something
}
你当然不能这样调用它:
f({ 1, 2, 3});
即使 std::vector
可以支撑初始化。但是,如果您替换 std::vector
与 std::initializer_list
,调用有效,编译器将正确推断 int
作为类型T
.然而,更有趣的是,在前一种情况下,您需要 #include <vector>
, 在后者中你不需要 #include <initializer_list>
.这让我思考,经过测试,我以某种方式意识到 std::initializer_list
不需要自己的标题,因此它在某种程度上是“基本”功能的一部分。
此外,为了让一切都有意义,std::initializer_list
应该以或多或少与 lambda 对可调用对象的方式相同(在最严格的意义上,即带有 operator()
的对象)。换句话说,未命名的大括号定义应该默认为 std::initializer_list
就像 lambda 是(大部分)未命名的可调用对象一样。
这个推理正确吗?此外,这种行为是否可以改变?如果可以,如何改变?
更新:initializer_list
的 header 被发现是从 iostream
传递过来的。 (真的很奇怪)。然而,问题仍然存在:为什么调用适用于 std::initializer_list
而不是std::vector
?
最佳答案
不包含 initializer_list
是不正确的 (so it requires a diagnostic)如果我们使用 std::initializer_list
则 header .我们可以从 [dcl.init.list]p2 中看到这一点:
... The template std::initializer_list is not predefined; if the header <initializer_list> is not included prior to a use of std::initializer_list — even an implicit use in which the type is not named (9.1.7.4) — the program is ill-formed.
您很可能会传递包含标题,它格式正确但会使您的代码更脆弱,因此请包含您使用的内容。
我们可以从一个实时的godbolt 示例中看到,如果没有包含,我们可以从gcc/clang/MSVC 获得所需的诊断信息。例如:
error: use of undeclared identifier 'std'
void foo( std::initializer_list<int>) {
^
包括<vector>
或 <iostream>
我们 no longer obtain a diagnostic .
[temp.deduct.type]p5 涵盖了为什么它没有按照您的预期进行推断。这告诉我们这是一个非推断的上下文:
The non-deduced contexts are:
...
- A function parameter for which the associated argument is an initializer list ([dcl.init.list]) but the parameter does not have a type for which deduction from an initializer list is specified ([temp.deduct.call]).> [ Example:template<class T> void g(T); g({1,2,3}); // error: no argument deduced for T
— end example ]
...
另见 [temp.deduct.call]p1 :
... Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context ([temp.deduct.type]) ...
关于c++ - std::initializer_list,大括号初始化和 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52924740/