简体   繁体   English

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

[英]How many times the constructors are called?

I am quite puzzled by the std::move stuff. 我很困惑std :: move的东西。 Assume I have this piece of code: 假设我有这段代码:

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

string s = foo();

How many times the string constructor is called? 调用字符串构造函数的次数是多少? Is it 2 or 3? 是2还是3? Is the compiler going to use move for this line? 编译器是否会使用此行的移动?

string s = foo();

If so, in the function I am not even returning rvalue reference, so how could the compiler invoke the move constructor? 如果是这样,在函数中我甚至没有返回rvalue引用,那么编译器怎么能调用move构造函数呢?

It depends on the compiler. 这取决于编译器。 In this case, the standard requires that there will be at least one constructor call. 在这种情况下,标准要求至少有一个构造函数调用。 Namely, the construction of t . 即, t的构造。

But the standard allows the possibility of two others: the move-construction of the value output of foo from t , and the move-construction of s from the value output of foo . 但是标准允许两个人的可能性:布展施工的价值输出的foot ,和布展施工s从价值输出foo Most decent compilers will forgo these constructors by constructing t directly in the memory for s . 大多数体面的编译器都会通过直接在s的内存中构造t来放弃这些构造函数。 This optimization is made possible because the standard allows these constructors to not be called if the compiler chooses not to. 这种优化是可能的,因为标准允许在编译器选择不执行时调用这些构造函数。

This is called copy/move "elision". 这称为复制/移动“省略”。

If so, in the function I am not even returning rvalue reference, so how could the compiler invoke the move constructor? 如果是这样,在函数中我甚至没有返回rvalue引用,那么编译器怎么能调用move构造函数呢?

You seem to be laboring under the misconception that && means "move", and that if there's no && somewhere, then movement can't happen. 你似乎在误解“ &&意味着“移动”,并且如果没有&&某个地方,那么运动就不会发生。 Or that move construction requires move , which also is not true. 或者移动建设需要move ,这也不是真的。

C++ is specified in such a way that certain kinds of expressions in certain places are considered valid to move from. C ++以某种方式指定,某些地方的某些表达式被认为是有效的。 This means that the value or reference will attempt to bind to a && parameter before binding to a & parameter. 这意味着该值或参考将试图绑定到&&结合到前参数&参数。 Temporaries, for example, will preferentially bind to a && parameter before a const& one. 例如,Temporaries将在const& one之前优先绑定到&&参数。 That's why temporaries used to construct values of that type will be moved from. 这就是为什么用于构造该类型值的临时工具将被移除。

If you have a function which returns a value of some type T , and a return expression is of the form return x , where x is a named variable of type T of automatic storage duration (ie: a function parameter or stack variable), then the standard requires that this return expression move construct the returned value from x . 如果你有一个返回某个类型T的值的函数,并且返回表达式的形式为return x ,其中x是自动存储持续时间类型T的命名变量(即:函数参数或堆栈变量),则该标准要求此返回表达式move构造x的返回值。

The return value of foo is a temporary. foo的返回值是暂时的。 The rules of C++ require that temporaries bind to && parameters before const& . C ++的规则要求temporaries在const&之前绑定到&&参数。 So you get move construction into s . 所以你将结构转移到s

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM