C++11 rvalues and move semantics confusion (return statement)(C++11 右值和移动语义混淆(返回语句))
问题描述
我正在尝试理解 C++11 的右值引用和移动语义.
I'm trying to understand rvalue references and move semantics of C++11.
这些例子有什么区别,哪些不做向量复制?
What is the difference between these examples, and which of them is going to do no vector copy?
std::vector<int> return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return tmp;
}
std::vector<int> &&rval_ref = return_vector();
第二个例子
std::vector<int>&& return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return std::move(tmp);
}
std::vector<int> &&rval_ref = return_vector();
第三个例子
std::vector<int> return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return std::move(tmp);
}
std::vector<int> &&rval_ref = return_vector();
推荐答案
第一个例子
std::vector<int> return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return tmp;
}
std::vector<int> &&rval_ref = return_vector();
第一个示例返回一个由 rval_ref
捕获的临时对象.该临时文件的生命周期将超过 rval_ref
定义,您可以像按值捕获它一样使用它.这与以下内容非常相似:
The first example returns a temporary which is caught by rval_ref
. That temporary will have its life extended beyond the rval_ref
definition and you can use it as if you had caught it by value. This is very similar to the following:
const std::vector<int>& rval_ref = return_vector();
除了在我的重写中你显然不能以非常量的方式使用 rval_ref
.
except that in my rewrite you obviously can't use rval_ref
in a non-const manner.
std::vector<int>&& return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return std::move(tmp);
}
std::vector<int> &&rval_ref = return_vector();
在第二个示例中,您创建了一个运行时错误.rval_ref
现在保存了对函数内部被破坏的 tmp
的引用.运气好的话,这段代码会立即崩溃.
In the second example you have created a run time error. rval_ref
now holds a reference to the destructed tmp
inside the function. With any luck, this code would immediately crash.
std::vector<int> return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return std::move(tmp);
}
std::vector<int> &&rval_ref = return_vector();
您的第三个示例大致相当于您的第一个示例.tmp
上的 std::move
是不必要的,实际上可能会降低性能,因为它会抑制返回值优化.
Your third example is roughly equivalent to your first. The std::move
on tmp
is unnecessary and can actually be a performance pessimization as it will inhibit return value optimization.
编写代码的最佳方式是:
The best way to code what you're doing is:
std::vector<int> return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return tmp;
}
std::vector<int> rval_ref = return_vector();
即就像在 C++03 中一样.tmp
在 return 语句中被隐式视为右值.它将通过返回值优化(不复制,不移动)返回,或者如果编译器决定它不能执行 RVO,那么它 将使用vector的移动构造函数来做返回.仅当未执行 RVO 且返回类型没有移动构造函数时,才会使用复制构造函数进行返回.
I.e. just as you would in C++03. tmp
is implicitly treated as an rvalue in the return statement. It will either be returned via return-value-optimization (no copy, no move), or if the compiler decides it can not perform RVO, then it will use vector's move constructor to do the return. Only if RVO is not performed, and if the returned type did not have a move constructor would the copy constructor be used for the return.
这篇关于C++11 右值和移动语义混淆(返回语句)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:C++11 右值和移动语义混淆(返回语句)
- XML Schema 到 C++ 类 2022-01-01
- 如何提取 __VA_ARGS__? 2022-01-01
- 将函数的返回值分配给引用 C++? 2022-01-01
- 从父 CMakeLists.txt 覆盖 CMake 中的默认选项(...)值 2021-01-01
- DoEvents 等效于 C++? 2021-01-01
- 将 hdc 内容复制到位图 2022-09-04
- 使用 __stdcall & 调用 DLLVS2013 中的 GetProcAddress() 2021-01-01
- GDB 不显示函数名 2022-01-01
- OpenGL 对象的 RAII 包装器 2021-01-01
- 哪个更快:if (bool) 或 if(int)? 2022-01-01