如何做一个C ++编译器决定何时呼吁的std ::矢量一个移动构造函数或任何对象[复制]

问题描述 投票:3回答:5

这个问题已经在这里有一个答案:

我读STD模板库书,并与STL容器章列举如下细节被搞糊涂了。显然,它指定的std ::向量操作和效果

Operation                     Effect

vector<Elem> c(c2)  | Copy constructor; creates a new vector as a copy of c2 (all elements are copied)
vector<Elem> c = c2 | Copy constructor; creates a new vector as a copy of c2 (all elements are copied)
vector<Elem> c(rv)  | Move constructor; creates a new vector, taking the contents of the rvalue rv (since C++11)
vector<Elem> c = rv | Move constructor; creates a new vector, taking the contents of the rvalue rv (since C++11)

显然,没有在语法两个移动和拷贝构造函数没有区别,那到底什么时候他们叫什么名字?

c++ c++11 stl
5个回答
4
投票

比方说您有一个函数f按值返回一个向量:

std::vector<int> f();

函数返回值是一个右值。

然后,让我们看看调用这个函数来初始化你的一个向量:

std::vector<int> v = f();

现在,编译器知道通过f返回的矢量不会被更多的使用,这是一个临时的对象,因此没有意义复制此临时对象,因为它只是被立即反正破坏。因此,编译器决定调用move构造函数来代替。


4
投票

此举构造函数被调用,其中是有意义的调用它,即移动对象,并用它此后没有意义,与原始对象已被修改(可能的),这是不希望:

std::vector<int> a = { 1 };
std::vector<int> b = a; //Let's say this called move constructor
int value = a[0]; //value is possibly not 1, the value may have changed due to the move

所以,在这种情况下,拷贝构造函数被调用:

std::vector<int> a = { 1, 2 };
std::vector<int> b = a; //Copy constructor

但是,在这里它调用移动的构造,因为它被分配给右值,或临时值:

void foo(std::vector<int>) {}
foo({ 1, 2 }); //move constructor

矢量{ 1, 2 }是一个临时的载体,谁在乎它是否已被修改?你永远不会知道,作为载体将得到尽快foo已经结束破坏。复制临时载体也只是浪费时间。


2
投票

也许你应该脱钩语义语法更好的理解。让我做一个类比,考虑下面的代码。

struct A {
  A(int i) {}
  A(const std::string& s) {}
};

现在,如果你找到下面的行,其构造函数将被调用?

A a(x);

你不能告诉它,因为你不知道x是否有类型为int或std ::字符串。这不是在你的例子太多不同,但随着移动语义编译器会检查该参数是右值与否。如果这样的A类提供了一个(移动)的构造的过载和x是一个rvalue参考,那么它会是优选的。


2
投票

显然,有两个移动和拷贝构造函数的语法没有区别

事实上,这是事实。这是不特定于std::vector要么,但一般适用于所有类型。复制初始化通过复制和移动具有完全相同的语法。这同样适用于拷贝赋值。

的差异来自参数表达式的类型。当参数是一个非const r值,此举构造/分配由过载分辨率是优选的。否则,将构造函数是不适用的,所以拷贝构造函数时使用。

我假定RV就像C2一个构造的对象

休旅车和C2似乎没有对象。他们显然对表达式的占位符。这本书可能是有关更清楚(也许是,摘录是断章取义,毕竟)。


-1
投票

拷贝构造函数的语法:类名(const的类名和)

移动构造函数的语法:类名(类名&&)

调用看起来相同在一起,但他们的声明是不同的。

参考:

http://en.cppreference.com/w/cpp/language/copy_constructor http://en.cppreference.com/w/cpp/language/move_constructor

© www.soinside.com 2019 - 2024. All rights reserved.