可以通过移动语义来更改或改进此C ++代码吗?

时间:2018-10-29 14:59:21

标签: c++ move compiler-optimization move-semantics

struct big_struct{
    vector<int> a_vector;
    map<string, int> a_map;
};

big_struct make_data(){
    big_struct return_this;
    // do stuff, build that data, etc
    return return_this;
}
int main(){

    auto data = make_data();
}

我已经看到将移动语义应用于构造函数,但是在这段代码中,我想知道大结构是否在返回时完全复制。我什至不确定它是否与移动语义有关。 C ++是否总是复制此类数据,或者是否进行了优化?可以更改或改进此代码吗?

返回矢量或地图的函数呢?该地图/矢量是否被复制?

2 个答案:

答案 0 :(得分:12)

您无需更改任何内容。您现在拥有的是rule of zero。由于std::mapstd::vector都是可移动的,因此您的班级会自动向其添加移动操作。

由于return_this是一个函数局部对象,它将被视为右值,它将为您移动或NRVO插入并且不会发生移动或复制。

您的代码将为return_this生成一个默认构造函数调用,为data产生一个移动构造函数调用,或者您将看到一个data的单个默认构造函数调用(NRVO使{{1 }}和return_this是同一件事)。

答案 1 :(得分:0)

here所述,您的类实际上有一个移动构造函数(隐式生成的一个),因此不应在您的代码中至少复制一次(在main中)。

一个问题是,您所依赖的是NRVO,并且不需要 来实现它(不像它的更简单的兄弟RVO那样)。在return语句中复制的机会非常小,但是机会很小,因此实际上不建议使用逐行返回(例如return std::move(return_this);)。如果您的函数中确实有单个return语句返回单个命名对象,则很有可能实际应用NRVO。