为什么我的代码打印 r 值 2 次而不是 rvalue 和 lvalue?

Why is my code printing rvalue 2 times instead of rvalue & lvalue?

所以想练习一下std::forward的用法,创建了一个Test class,有2个构造函数。 1 个 T& 和另一个 T&& 作为重载。 T& 打印 lvalue,而 T&& 打印 rvalue 所以我知道正在使用哪个构造函数。我在堆栈上创建了 2 个 class 实例,令我惊讶的是它们都使用了 T&& 重载。

#include <iostream>
#include <type_traits>
#include <utility>

template <class T> auto forward(T &&t) {
  if constexpr (std::is_lvalue_reference<T>::value) {
    return t;
  }
  return std::move(t);
}

template <class T> class Test {
public:
  Test(T &) { std::cout << "lvalue" << std::endl; };
  Test(T &&) { std::cout << "rvalue" << std::endl; };
};

int main() {
  int x = 5;
  Test<int> a(forward(3));
  Test<int> b(forward(x));
  return 0;
}

我尝试使用原始的 std::forward 函数并实现它,但两次它都打印了 rvalue x2。我做错了什么?

您的问题源于 forward 的 return 类型。您使用 auto 作为 return 类型,这不会为您推断出参考。这意味着当你做 return 时,无论它 return 来自哪个分支,你都 return 按值计算,这意味着你有一个 prvalue。

你需要的是 decltype(auto) 所以你 return 一个右值或左值引用,这取决于 return 语句。使用

template <class T> decltype(auto) forward(T &&t) {
  if constexpr (std::is_lvalue_reference<T>::value)
    return t;
  else
    return std::move(t);
}

给你输出:

rvalue
lvalue