此样本中的矢量是否复制了两次?

Ago*_*iro 2 c++ c++11

C++书籍中的数据结构和算法分析包含图1.26中第63页的以下代码片段,用于矩阵类(某些部分被省略或截断):

#include <vector>
using namespace std;

template <typename Object>
class matrix
{
  public:
    matrix(int rows, int cols);

    matrix(vector<vector<Object>> v) : array{v} { }        
    matrix(vector<vector<Object>>&& v) : array{std::move(v)} { }

    const vector<Object>& operator[](int row) const;
    vector<Object>& operator[](int row);
  private:
    vector<vector<Object>> array;
};
Run Code Online (Sandbox Code Playgroud)

matrix(vector<vector<Object>> v)构造函数中v被复制两次?签名应该matrix(const vector<vector<Object>>& v)改为吗?

勘误表中没有提到这个问题:https://users.cs.fiu.edu/~weiss/dsaa_c++4/errata.html

书籍引用:

Weiss,MA:C++中的数据结构和算法分析,国际版,2014,Pearson Education Limited.

Rei*_*ica 6

是的,第一个构造函数应该肯定拿vconst &; 否则,当从rvalue构造时,你将得到模糊的重载决策(值和rvalue引用都是同样好的匹配).

[实例]

但是也要回答关于复制两次的问题:如果rvalue-reference构造函数不存在,那么将左值传递给第一个将确实导致两个副本(一次进入v,一次进入array).传递右值可能会忽略第一个副本.

事实上,只有一个这样的构造函数,这个类就可以了:

matrix(vector<vector<Object>> v) : array{std::move(v)} { }
Run Code Online (Sandbox Code Playgroud)

当使用左值初始化时,这会导致复制+移动,并且当使用右值初始化时,(elidable)移动+移动.