0

最近我一直在尝试理解移动语义并提出了一个问题。

这个问题已经在这里讨论过了。

我实现了第一个变体并检查它是否返回左值或右值:

#include <iostream>
using namespace std;

template <typename T>
T&& my_forward(T&& x) {
    return static_cast<T&&> (x);
}

int main() {
    int a = 5;
    &my_forward(a); // l-value
    return 0;
}

因此,如果我传递 l-value,它会返回 l-value(编译,因为我可以从 l-value 获取地址),如果我这样做:

&my_forward(int(5)); // r-value with int&& type

我的代码无法编译,因为 my_forward 返回了 r 值。在上面的问题中,他们说这个实现和标准实现之间的区别(分别使用 std::remove_reference 和 2 个不同的参数与 & 和 && )是我的实现一直返回左值,但正如我所展示的那样返回右值和左值。

所以我想知道,为什么我不能像那样实现 std::forward ?在什么特定情况下,它会显示标准之间的差异?另外,为什么我应该将 T 指定为模板并且不能让它用参数类型定义自己?

4

2 回答 2

3

在真实环境中尝试像 std forward 一样对它进行 hsing。你的不起作用;

void test(std::vector<int>&&){}

template<class T>
void foo(T&&t){
  test(my_forward<T>(t));
}

foo( std::vector<int>{} );

以上不编译。它与std::forward.

除了块引用生命周期延长之外,您的转发没有任何用处。同时,std::forward是有条件的std::move

有名字的所有东西都是左值,但是向前移动有名字的右值引用。

带有名称的右值引用是左值。

于 2017-02-19T15:56:59.460 回答
1

不幸的是,获取地址在您的上下文中不是一个有用的操作,因为它查看了错误的值类别:

  • 您可以获取glvalue 的地址,但不能获取prvalue。glvalue 表示“位置”(即对象所在的位置),prvalue 表示“初始化”(即对象具有什么值)。

  • 您可以从右值中窃取资源,但不能从左值中窃取。左值引用绑定到左值,右值引用绑定到右值。的要点std::forward是在提供右值时将参数转换为右值,并在提供左值时将参数转换为左值。

std::forward返回一个右值时,它实际上返回一个xvalue,xvalues既是右值又是glvalues:

                    lvalue       f() for "T& f();",   decltype(f()) is T&
                  /
          glvalue
        /         \
  value             xvalue       f() for "T&& f();",  decltype(f()) is T&&
        \         /
           rvalue
                  \
                    prvalue      f() for "T f();",    decltype(f()) is T
于 2017-02-19T16:13:59.333 回答