【发布时间】:2014-11-06 20:02:47
【问题描述】:
clang 3.5.0 和 gcc 4.9.1 从代码生成的可执行文件
#include <iostream>
struct Foo
{
Foo() { std::cout << "Foo()" << std::endl; }
Foo(int x) { std::cout << "Foo(int = " << x << ")" << std::endl; }
Foo(int x, int y) { std::cout << "Foo(int = " << x << ", int = " << y << ")" << std::endl; }
};
int main() // Output
{ // ---------------------
auto a = Foo(); // Foo()
auto b = Foo(1); // Foo(int = 1)
auto c = Foo(2, 3); // Foo(int = 2, int = 3)
auto d = Foo{}; // Foo()
auto e = Foo{1}; // Foo(int = 1)
auto f = Foo{2, 3}; // Foo(int = 2, int = 3)
auto g = Foo({}); // Foo(int = 0) <<< Why?
auto h = Foo({1}); // Foo(int = 1)
auto i = Foo({2, 3}); // Foo(int = 2, int = 3)
}
按照评论行事。
来自cppreference: cpp/language/list initialization:
[...] T( { arg1, arg2, ... } ) (7) [...]T 类型对象的列表初始化的效果是:
如果
T是聚合类型,则执行聚合初始化。否则,如果braced-init-list为空且
T是具有默认构造函数的类类型,则执行值初始化。[...]
我的结论是Foo({}) 应该调用默认构造函数。
错误在哪里?
【问题讨论】:
-
错误在 cppreference 中。
-
修复了 cppreference 以读取“从 非括号括号初始化列表中类型为
T的对象的列表初始化效果是...”更清楚了吗? -
也许将
T({...})替换为U({...})可能是一个好主意,以避免引用T的文本出现问题,这里不正确。 -
-
@precarious 它仍然是精确的。如果删除了 int 构造函数,您将调用复制/移动构造函数。
标签: c++ language-lawyer c++14 list-initialization value-initialization