#include <initializer_list>
#include <iostream>
using namespace std;
struct Y {};
struct X
{
X(initializer_list<Y>) { cout << "yay" << endl; }
explicit X() { cout << "boo" << endl; }
};
X f()
{
return {};
}
int main()
{
f();
return 0;
}
打印出“boo”。为什么不打印出“yay”?
无论如何要区分以下两种结构:
X()
X{}
或
return X();
return {};
或
void g(const X&)
g(X())
g({})
感谢。
答案 0 :(得分:5)
无论如何要区分以下两种结构:
没有。它们不是不同的结构。
{}构造函数语法的主要目的是引入统一初始化,使初始化在任何地方都相同。如果他们之间存在差异,那就不一致了。
如果要使用空的初始化列表构造函数,则必须声明您正在显式传递初始化列表。像这样:return initializer_list<Y>{};
当然,统一初始化的另一个目的是不必输入类型名,所以你可以用return {{}};
答案 1 :(得分:5)
return {};
将始终使用默认构造函数(如果有)。
return X({});
或return {{}};
将从空的初始化列表构建。
答案 2 :(得分:1)
它使用默认构造函数,因为使用{}
的列表初始化意味着始终是一种简短的值初始化形式,忽略其他构造函数,即使它们是初始化列表构造函数。
无论如何要区分以下两种结构:......
X()
始终是值初始化,而X{}
仅是值初始化,如果X
具有默认构造函数。如果它是聚合,则X{}
是聚合初始化(递归地将X
的成员初始化为{}
)。如果它只有初始化列表构造函数而没有默认构造函数,那么X()
无效且X{}
可能有效
struct A { A(initializer_list<int>); };
A a = A{}; // valid
A b = A(); // invalid
基本上,X{}
的作用取决于X
是什么。但X()
总是初始化值。
...或返回X(); vs return {};
微妙的提及......在return {}
中,目标是复制列表初始化的,而在return X();
中,首先直接初始化X
。但即使它是copy-list-initialized,也可以使用explicit
默认构造函数,因为值初始化不关心explicit
。但是,如果执行return {}
并尝试使用显式非默认构造函数,则会出错
struct A {
explicit A(initializer_list<int>);
};
A f() { return {}; } // error!
struct B {
explicit B();
};
B g() { return {}; } // OK
答案 3 :(得分:0)
你可以更明确一点:
return initializer_list<Y>();