这只是偏好还是有特定情况下需要使用其中一种变体?我指的是以下几种初始化方式:
T t(e); // direct initialization
T t = e; // copy initialization
这只是偏好还是有特定情况下需要使用其中一种变体?我指的是以下几种初始化方式:
T t(e); // direct initialization
T t = e; // copy initialization
T x = a;
T x(a);
T
为类类型而a
为不同类型时(请参见Alf评论中不涉及转换的上下文示例)。考虑以下代码:class Test
{
public:
explicit Test(int i) { /* ... */ }
};
int main()
{
Test t(0); // OK : calls Test::Test(int)
Test u = 0; // KO : constructor is marked explicit
}
引述标准(8.5/14)的意思是:
main
函数的第二行,会考虑用户自定义转换序列。由于使用explicit
关键字禁止了对Test
构造函数进行隐式转换,因此第二行代码无法编译。a
是表达式T()
。 :-)那么复制初始化的语法形式大体上等同于默认初始化(除了可能涉及临时和复制),而直接初始化的语法形式将解释为函数声明,“最令人烦恼的解析”。此外,请考虑显式复制构造函数的情况。根据允许的模糊程度,请考虑花括号初始化程序。因此,至少有3种情况。但直接的反例是“显式”复制构造函数。干杯! - Cheers and hth. - Alf直接初始化就像这样
std::istringstream stream( "blah blah" );
当所涉及的类型(此处为C++标准库中的std::istringstream
)没有可访问的复制构造函数时,需要使用move初始化
。
像这样进行复制初始化:
std::istringstream stream = "blah blah"; //! NOT VALID
需要一个可访问的复制构造函数,因为它被执行时,似乎在等号右侧创建了一个临时对象,然后该临时对象用于初始化正在声明的变量。
在另一方面,在C++98中需要使用复制初始化语法才能使用花括号初始化程序。例如,直接初始化无法用于初始化聚合体。但是,您可以使用带有花括号初始化程序的复制初始化:
#include <string>
using namespace std;
struct Answer
{
int nVotes;
string description;
};
int main()
{
Answer const incorrect = { 26, "they're the same!" };
Answer const correct = { -1, "nah, they're different, actually" };
}
因此,存在显著差异。
通常我更喜欢使用复制初始化语法,因为它更加清晰。但有时候,就像上面展示的那样,不幸的是,直接初始化是必要的。一些人,例如C++教材作者Francis Glassborow,已经将直接初始化作为他们首选的初始化语法(我不确定为什么,对我来说不太清晰,并且引入了“最棘手的解析”问题),对于他们来说,在某些情况下需要复制初始化是不幸的。
祝好!