Tl;DR
此行为受提案和演进工作组问题的约束。关于这是否被视为 C++14 缺陷或 C++1z 提案存在一些模糊性。如果事实证明这是 C++14 缺陷,则 gcc 的行为对于 C++14 来说是正确的。另一方面,如果这确实是一个 C++1z 提案,那么 clang 和 icpc 就会表现出正确的行为。
Details
看起来这个案例被覆盖了N3681 http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3681.html其中说:
自动和支撑初始化器会导致可教性问题;我们想
教人们使用统一初始化,但我们需要
特别告诉程序员避免使用 auto 大括号。在 C++14 中,我们
现在auto和括号有问题的情况更多了;返回类型
函数的推导部分避免了这个问题,因为返回
大括号列表不起作用,因为它不是表达式。然而,返回
从花括号初始化器初始化的自动变量仍然返回
一个初始化列表,引发未定义的行为。拉姆达初始化
捕获也有同样的问题。本文建议改变一个
大括号初始化的 auto 不会推导出初始化列表,并且
在大括号初始化程序具有的情况下禁止大括号初始化自动
不止一种元素。
并提供以下示例:
auto x = foo(); // copy-initialization
auto x{foo}; // direct-initialization, initializes an initializer_list
int x = foo(); // copy-initialization
int x{foo}; // direct-initialization
So I think clang is currently correct, the latest version of clang provides this warning:
警告:使用推导类型直接列表初始化变量
将在 Clang 的未来版本中改变含义;插入一个“=”
避免行为改变 [-Wfuture-compat]
From 专家工作组第 161 期 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4422.html#161 that N3922 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html为此被采用。
正如 Praetorian 指出的那样,该提案建议这是一个 C++14 缺陷:
EWG 的指示是,我们认为这是 C++14 中的一个缺陷。
但铿锵的C++1z 实现状态说明 http://clang.llvm.org/cxx_status.html这是一个未实现的 C++1z 提案。
因此,如果这是一个 C++14 缺陷,那么 gcc 就会正确,但我不清楚这是否真的是一个缺陷或一个提案。
T.C.指出在一个在这里发表评论 https://stackoverflow.com/questions/33500320/why-this-variable-isnt-deduced-as-initializer-list-in-g-in-c14#comment54798222_33500320那它似乎是 clang 开发者 http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20150209/123102.html确实打算向后移植这个。这种事还没有发生,也不清楚为什么。