我最近遇到了这段代码:
struct Foo{};
int main()
{
Foo a;
// clang++ deduces std::initializer_list
// g++5.1 deduces Foo
auto b{a};
a = b;
}
它在 g++5.1 中编译良好,但在 clang++ 中失败(-std=c++11
和 -std=c++14
一起使用,结果相同)。原因是 clang++ 推导出b
的类型为 std::initializer_list<Foo>
,而g++5.1
推导为 Foo
。AFAIK,类型确实应该(确实违反直觉)std::initializer_list
在这里。为什么 g++5 将类型推导出为 Foo
?
关于 C++1z 的建议,它实现了大括号初始化的新类型扣除规则 (N3922),我想 gcc 实现了它们:
对于直接列表初始化:
1. 对于只有一个元素的大括号初始化列表,将从该条目中扣除自动扣除;
2. 对于包含多个元素的大括号初始化列表,自动扣除将格式不正确。[示例:
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int> auto x2 = { 1, 2.0 }; // error: cannot deduce element type auto x3{ 1, 2 }; // error: not a single element auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int> auto x5{ 3 }; // decltype(x5) is int.
-- 结束示例]
这是关于"独角兽初始化"的新变化的 gcc 补丁。