C++ 在c+;中使用move有什么好处+;

C++ 在c+;中使用move有什么好处+;,c++,c++17,C++,C++17,我有以下功能 std::pair<Eigen::ArrayXXd, Eigen::VectorXd> f(...){ ... auto a = Eigen::ArrayXXd(N,M); auto b = Eigen::VectorXd(M); ... return {std::move(a), std::move(b)}; } int main() { ... const auto &[a_up, b_up] =

我有以下功能

std::pair<Eigen::ArrayXXd, Eigen::VectorXd> f(...){
    ...
    auto a = Eigen::ArrayXXd(N,M);
    auto b = Eigen::VectorXd(M);
    ...
    return {std::move(a), std::move(b)};
}

int main() {
     ...
     const auto &[a_up, b_up] = f(...);
     writeToFile("b_up.txt", b_up);
     ...
}
std::对f(…){
...
自动a=本征::arrayxd(N,M);
自动b=本征::矢量xd(M);
...
返回{std::move(a),std::move(b)};
}
int main(){
...
常数自动&[a_向上,b_向上]=f(…);
写入文件(“b_up.txt”,b_up);
...
}

在函数
f
中,我们分配并初始化特征数组和向量
a
b
。使用
move
-关键字,我们仍然使用在函数
f
中分配的相同内存。由于
const auto&b_up=f(…)
也在函数
f
之外,使用了相同的内存空间,因此我们不必复制任何内容。这是正确的吗?但是,与通过引用传递相比,它有什么优势呢。是否发生了复制?

函数
f
中的
return
语句创建了
std::pair
,由于RVO,即使您编写了以下代码,也不会进一步复制该开关:

auto ab_pair=f(…);
但是仍然必须移动或复制
a
b
,但是有一种方法可以使用
std::pieclewise_construct
在适当的位置构造该对,然后通过引用RVO返回:

autof(…){
std::配对结果{
std::分段_构造,
std::make_tuple(N,M),
std::生成元组(M),
};
...
返回结果;
}

函数
f
中的
return
语句创建了
std::pair
,由于RVO的原因,即使您写入:

auto ab_pair=f(…);
但是仍然必须移动或复制
a
b
,但是有一种方法可以使用
std::pieclewise_construct
在适当的位置构造该对,然后通过引用RVO返回:

autof(…){
std::配对结果{
std::分段_构造,
std::make_tuple(N,M),
std::生成元组(M),
};
...
返回结果;
}

编译时是否没有警告?因为在警告打开的情况下,编译器应该已经告诉您删除它(这是一种悲观情绪)
std::move
返回一个引用,这比仅为编译器执行RVO更麻烦,更糟糕的是,您在那里返回的两个引用实际上可能是同一个对象。@Damon不,我得到了正确的结果。这更多的是一个理论问题。因为我经常看到这个
move
语句,我想知道这是否比传递引用好得多。是的,当然你得到了正确的结果,不管怎样,你都得到了。只是从性能上看,搬家更多的是一种劣势,而不是优势。谷歌表示“移动悲观化”或“复制省略规则”或类似术语。第一个随机点击:@Damon关于移动悲观化的担忧(我的意思是使用
返回移动(结果);
)在这里不适用,因为返回的类型与移动对象的类型不同。如问题所示,使用
move
是可以的,也是可取的。@Suslik替代方法是不使用
move
返回{a,b}。但这将复制
a
b
,以便构造返回的
std::pair
对象。(当然,我假设所涉及类型的移动构造远比复制构造便宜。)您是在没有警告的情况下编译的吗?因为在警告打开的情况下,编译器应该已经告诉您删除它(这是一种悲观情绪)
std::move
返回一个引用,这比仅为编译器执行RVO更麻烦,更糟糕的是,您在那里返回的两个引用实际上可能是同一个对象。@Damon不,我得到了正确的结果。这更多的是一个理论问题。因为我经常看到这个
move
语句,我想知道这是否比传递引用好得多。是的,当然你得到了正确的结果,不管怎样,你都得到了。只是从性能上看,搬家更多的是一种劣势,而不是优势。谷歌表示“移动悲观化”或“复制省略规则”或类似术语。第一个随机点击:@Damon关于移动悲观化的担忧(我的意思是使用
返回移动(结果);
)在这里不适用,因为返回的类型与移动对象的类型不同。如问题所示,使用
move
是可以的,也是可取的。@Suslik替代方法是不使用
move
返回{a,b}。但这将复制
a
b
,以便构造返回的
std::pair
对象。(当然,我假设所涉及类型的移动构造远比复制构造便宜。)