调用构造函数的次数是多少?

时间:2013-09-05 03:47:46

标签: c++ c++11 constructor move-semantics

我对std :: move的东西感到很困惑。假设我有这个 一段代码:

string foo() {
  string t = "xxxx";
  return t;
}

string s = foo();

调用字符串构造函数的次数是多少?是2还是3? 编译器是否会对此行使用move?

string s = foo();

如果是这样,在函数中我甚至没有返回rvalue引用,那怎么可能呢 编译器调用移动构造函数?

1 个答案:

答案 0 :(得分:4)

这取决于编译器。在这种情况下,标准要求至少有一个构造函数调用。即,构造t

但该标准允许另外两个的可能性:从foo移动构建t的值输出,以及从s移动构造foo t。大多数体面的编译器都会通过在s的内存中直接构造&&来放弃这些构造函数。这种优化是可能的,因为如果编译器选择不这样做,标准允许不调用这些构造函数。

这称为复制/移动“省略”。

  

如果是这样,在函数中我甚至没有返回rvalue引用,那么编译器怎么能调用move构造函数呢?

你似乎在误解&&意味着“移动”,并且如果某处没有move,那么就不会发生这种运动。或者移动构造需要&&,这也不是真的。

C ++的指定方式使某些地方的某些表达式被认为是有效的。这意味着值或引用将在绑定到&参数之前尝试绑定到&&参数。例如,Temporaries将在const&之前优先绑定到T参数。这就是为什么用于构造该类型值的临时工具将被移除。

如果你有一个返回某种类型return x的值的函数,并且返回表达式的格式为x,其中T是{{1}类型的命名变量自动存储持续时间(即:函数参数或堆栈变量),然后标准要求此返回表达式移动构造从x返回的值。

foo的返回值是暂时的。 C ++规则要求临时值在&&之前绑定到const&参数。因此,您将构建移动到s