它是简单的偏好还是有特定的情况需要一个而不是另一个?我指的是以下变体进行初始化
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
对于其他复制初始化情况,例如我的示例中的第二行,考虑了用户定义的转换顺序。由于关键字Test
不允许使用构造函数进行隐式转换explicit
,因此第二行无法编译。直接初始化像
std::istringstream stream( "blah blah" );
当有问题的类型(此处std::istringstream
来自 C++ 标准库)没有可访问的复制构造函数时,这是必需的。
复制初始化,例如
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,转而将直接初始化作为他们首选的初始化语法(我不知道为什么,我的眼睛不太清楚,并引入了“最令人头疼的解析”问题),并且对他们来说不幸的是,在某些情况下需要进行复制初始化。
干杯&hth.,