为什么std :: move具有向前引用? [英] Why does std::move take a forward reference?

查看:89
本文介绍了为什么std :: move具有向前引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

std::move的实现基本上是这样的:

The implementation of std::move basically looks like this:

template<typename T>
typename std::remove_reference<T>::type&&
move(T&& t)
{
    return static_cast<typename std::remove_reference<T>::type&&>(t);
}

请注意,std::move的参数是通用引用(也称为转发引用,但此处不转发).也就是说,您可以同时std::move左值和右值:

Note that the parameter of std::move is a universal reference (also known as a forwarding reference, but we're not forwarding here). That is, you can std::move both lvalues and rvalues:

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

但是由于std::move的全部要点是强制转换为右值,为什么我们甚至允许使用std::move右值?如果std::move只接受左值,那会更有意义吗?

But since the whole point of std::move is to cast to an rvalue, why are we even allowed to std::move rvalues? Wouldn't it make more sense if std::move would only accept lvalues?

template<typename T>
T&&
move(T& t)
{
    return static_cast<T&&>(t);
}

那么荒谬的表达式std::move(b + c)会导致编译时错误.

Then the nonsensical expression std::move(b + c) would cause a compile-time error.

对于初学者来说,std::move的上述实现也将更容易理解,因为该代码完全按照其看起来的样子进行操作:它需要一个左值并返回一个右值.您不必了解通用引用,引用折叠和元函数.

The above implementation of std::move would also be much easier to understand for beginners, because the code does exactly what it appears to do: It takes an lvalue and returns an rvalue. You don't have to understand universal references, reference collapsing and meta functions.

那为什么std::move被设计成同时接受左值和右值?

So why was std::move designed to take both lvalues and rvalues?

推荐答案

以下是一些简化到极端的示例:

Here is some example simplified to the extreme:

#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
}

上面的情况可能会出现在通用代码中,例如,当使用具有返回代理对象(rvalues)的特殊化的容器时,并且您可能不知道客户端是否将使用特殊化,因此您想要无条件的支持移动语义.

Cases like the one above may appear in generic code, for example when using containers which have specializations that return proxy objects (rvalues), and you may not know whether the client will be using the specialization or not, so you want unconditional support for move semantics.

这篇关于为什么std :: move具有向前引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆