C++ 使用std::move是否有任何性能优势? 请考虑此代码: #include <iostream> #include <vector> #include <utility> std::vector<int> vecTest; int main() { int someRval = 3; vecTest.push_back(someRval); vecTest.push_back(std::move(someRval)); return 0; } #包括 #包括 #包括 std::向量向量测试; int main() { int-someRval=3; vecTest.向后推(someRval); vecTest.push_back(标准::move(someRval)); 返回0; }

C++ 使用std::move是否有任何性能优势? 请考虑此代码: #include <iostream> #include <vector> #include <utility> std::vector<int> vecTest; int main() { int someRval = 3; vecTest.push_back(someRval); vecTest.push_back(std::move(someRval)); return 0; } #包括 #包括 #包括 std::向量向量测试; int main() { int-someRval=3; vecTest.向后推(someRval); vecTest.push_back(标准::move(someRval)); 返回0; },c++,c++11,C++,C++11,据我所知,someRval的值将在第一次调用push_back()时复制到vecTest中,但在第二次调用时,someRval生成一个x值。我的问题是,是否会有任何性能方面的好处,我的意思是,可能不使用int,但在使用更大的对象时,是否会有一些性能方面的好处?移动int或甚至char*之类的“基本”类型与复制它们没有什么不同 复杂类型,如std::string,可以使用您愿意牺牲源对象状态的信息,以使移动比复制更高效。是的,但这取决于应用程序的详细信息—对象的大小和操作的频率 将其强制转换为r值

据我所知,
someRval
的值将在第一次调用
push_back()
时复制到vecTest中,但在第二次调用时,someRval生成一个x值。我的问题是,是否会有任何性能方面的好处,我的意思是,可能不使用
int
,但在使用更大的对象时,是否会有一些性能方面的好处?

移动
int
或甚至
char*
之类的“基本”类型与复制它们没有什么不同


复杂类型,如
std::string
,可以使用您愿意牺牲源对象状态的信息,以使移动比复制更高效。

是的,但这取决于应用程序的详细信息—对象的大小和操作的频率

将其强制转换为r值并移动(使用
std:move()
)可避免复制。如果对象的大小足够大,则可以节省时间(例如,考虑一个具有1000 000个双倍的数组-复制它通常意味着复制4 MB或更多的内存)。
另一点是频率——如果您的代码经常执行相应的操作,那么它可以累积相当多的时间

请注意,源对象在过程中被销毁(变得不可用),这对于您的逻辑来说可能是可接受的,也可能是不可接受的——您需要理解它并相应地编写代码。如果之后仍然需要源对象,那么它显然无法工作


通常,除非需要优化,否则不要进行优化。

移动带来的性能好处通常来自于排除动态分配

考虑一个过于简化(且幼稚)的
字符串
(缺少复制分配运算符和移动分配运算符):

这很好,但是如果字符串变长,这里的复制构造函数可能会很昂贵。但是,复制构造函数必须复制所有内容,因为它不允许接触
其他
对象,它必须完全按照其名称执行,即复制内容。如果你需要一个字符串的副本,这就是你必须付出的代价,但是如果你只想使用字符串的状态,而不关心它之后会发生什么,你最好移动它

移动它只需要将
other
对象保持在某种有效状态,这样我们就可以使用
other
中的所有内容,这正是我们想要的。现在,我们所要做的不是复制
数据
指针指向的内容,而是将
数据
指针重新分配到
其他
中的一个,我们基本上是在窃取
其他
的内容,我们也会很好地将原始
数据
指针设置为
空PTR

MyString(MyString&& other)
{
    data = other.data;
    other.data = nullptr;
}
好了,这就是我们要做的。这显然比复制构造函数复制整个缓冲区要快得多


.

转换为右值,而不是左值。对
int
s没有任何区别。对于移动构造函数比复制构造函数效率更高的类(例如,
std::string
)来说,如果您问错了问题,则会产生不同。如果在概念上将对象的值移动到向量中(因此不再使用该对象),则应该移动到向量中。正确地表达您的意图,性能将是它所需要的。我知道这只是一个示例,但是为了完整性,应该在move构造函数的开头添加一个检查,以确保
other
this
不同,如果是这种情况,则不应执行任何操作。
MyString(MyString&& other)
{
    data = other.data;
    other.data = nullptr;
}