初始化:T x(值)与T x =当值为T时的值

rpg*_*rpg 2 c++ initialization

T x(value)通常是更好的选择,因为它将直接用值初始化x,而T x = value可能会创建一个临时值,具体取决于值的类型.在值为T类型的特殊情况下,我的猜测是表达式T x = value将始终产生一个复制构造函数调用.我对么?

我问过这个问题,因为我开始认为第一种语法太丑陋而且难以理解,特别是当值是函数调用的结果时.例如:

  • const std::string path(attributes.data(pathAttrib));
  • const std::string path = attributes.data(pathAttrib);

小智 5

T x(value)通常是更好的选择,因为它会直接用值初始化x,而T x = value根据值的类型可能会创建一个临时值.

你几乎是对的,更好的选择是最清晰的语法.以下是两者的不同之处:

初始化的形式(使用括号或=)通常是无关紧要的,但是当被初始化的实体具有类类型时会很重要... [8.5/11]

struct A {
  A(int) {}
};
struct B {
  explicit B(int) {}
};

int main() {
  { A obj (42); } // succeeds
  { A obj = 42; } // succeeds

  { B obj (42); } // succeeds
  { B obj = 42; } // fails
}
Run Code Online (Sandbox Code Playgroud)

隐式转换是必需的,所以像vector<int> v = 3;失败一样,但这看起来不对,对吧?任何副本都可能被删除.我不记得发现这是我写过的任何东西的瓶颈,我很久以前就不再担心了:只需使用最清晰的语法.


在值为T类型的特殊情况下,我的猜测是表达式T x = value总是会产生一个复制构造函数调用.我对么?

不,您不能保证始终会调用复制程序,但必须可以访问它.例如,在上面的特定情况下,value作为函数的返回值,标准明确允许省略这些副本.

  • 但是如果`value`是类型`T`就没有副本也没有语义差异,这就是问题所要求的.[8.5/14] (2认同)
  • 我明白你在说什么.但是,我们不知道函数是通过值还是通过引用返回.我的理解是,在源类型与目标相同的情况下,直接初始化是否保证复制构造函数不会对复制 - 初始化进行额外的调用.这是我对标准的解释,两个版本都是等价的.显然,在这个特定的复制初始化情况下,必须选择复制构造函数来初始化目标,无论初始化器是临时的是正交问题. (2认同)