在 return 语句中的构造函数中移动语义

move semantics in constructor in return statement

我知道当 returning 局部变量以保留 RVO 时,我们应该允许编译器通过 returning 像这样的值

来执行移动省略
std::vector<double> some_func(){
    std::vector<double> my_vector;
    //do something
    return my_vector;
}

而不是

std::vector<double> some_func(){
    std::vector<double> my_vector;
    //do something
    return std::move(my_vector);
}

但是,如果我们在 return 语句中构造一个对象,请在构造函数中使用 std::move 来帮助、阻碍或不做任何事情来提高效率或妨碍编译器?

作为示例考虑这两个实现

std::pair<std::vector<double>,std::vector<double> > some_func()
    std::vector<double> my_vec_a;
    std::vector<double> my_vec_b;
    //do something
    return std::make_pair(my_vec_a,my_vec_b);
}

std::pair<std::vector<double>,std::vector<double> > some_func()
    std::vector<double> my_vec_a;
    std::vector<double> my_vec_b;
    //do something
    return std::make_pair(std::move(my_vec_a),std::move(my_vec_b));
}

所以

  1. 首先,编译器会认识到my_vec_amy_vec_b会超出范围并优化return语句中的构造吗?
  2. 如果是这样,在第二个中使用 std::move 会阻止优化吗?
  3. 或者第二个选项会更有效率吗?

这个效率更高:

std::pair<std::vector<double>,std::vector<double> > some_func() { 
    std::vector<double> my_vec_a;
    std::vector<double> my_vec_b;
    //do something
    return std::make_pair(std::move(my_vec_a),std::move(my_vec_b));
}

如果不调用 std::move,将复制两个向量。

然而,问题不在于实际 return。这是正在构造的对中的两个向量是从左值构造的;编译器不能选择在那里使用移动构造函数,除非您通过 std::move.

明确告诉它