fre*_*low 9 c++ rvalue move-semantics c++11 forwarding-reference
实现std::move基本上如下:
template<typename T>
typename std::remove_reference<T>::type&&
move(T&& t)
{
return static_cast<typename std::remove_reference<T>::type&&>(t);
}
Run Code Online (Sandbox Code Playgroud)
请注意,参数std::move是通用引用(也称为转发引用,但我们不在此处转发).也就是说,你可以std::move使用左值和左值:
std::string a, b, c;
// ...
foo(std::move(a)); // fine, a is an lvalue
foo(std::move(b + c)); // nonsense, b + c is already an rvalue
Run Code Online (Sandbox Code Playgroud)
但是,由于整个观点std::move都是为了施展到一个rvalue,为什么我们甚至允许std::movervalues呢?如果std::move只接受左值,那会不会更有意义?
template<typename T>
T&&
move(T& t)
{
return static_cast<T&&>(t);
}
Run Code Online (Sandbox Code Playgroud)
然后,无意义的表达式std::move(b + c)将导致编译时错误.
std::move对于初学者来说,上面的实现也会更容易理解,因为代码完全按照它的样子执行:它需要一个左值并返回一个右值.您不必了解通用引用,引用折叠和元函数.
那么为什么std::move设计同时采用左值和左值?
vso*_*tco 10
以下是一些简化为极端的示例:
#include <iostream>
#include <vector>
template<typename T>
T&& my_move(T& t)
{
return static_cast<T&&>(t);
}
int main()
{
std::vector<bool> v{true};
std::move(v[0]); // std::move on rvalue, OK
my_move(v[0]); // my_move on rvalue, OOPS
}
Run Code Online (Sandbox Code Playgroud)
像上面这样的情况可能出现在通用代码中,例如当使用具有返回代理对象(rvalues)的特化的容器时,您可能不知道客户端是否将使用特化,因此您希望无条件支持移动语义.
| 归档时间: |
|
| 查看次数: |
606 次 |
| 最近记录: |