gpt4 book ai didi

c++ - 为什么 std::move 需要前向引用?

转载 作者:可可西里 更新时间:2023-11-01 16:35:28 25 4
gpt4 key购买 nike

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

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 左值和右值:

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 只接受左值不是更有意义吗?

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

然后无意义的表达式 std::move(b + c) 将导致编译时错误。

std::move 的上述实现对于初学者来说也更容易理解,因为代码完全按照它看起来做的那样:它接受一个左值并返回一个右值。您不必了解通用引用、引用折叠和元函数。

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

最佳答案

这里是一些简化到极致的例子:

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

像上面这样的情况可能会出现在通用代码中,例如当使用具有返回代理对象(右值)的特化的容器时,您可能不知道客户端是否会使用特化,所以您想要无条件支持 move 语义。

关于c++ - 为什么 std::move 需要前向引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28936258/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com