【问题标题】:Why is my code printing rvalue 2 times instead of rvalue & lvalue?为什么我的代码打印 r 值 2 次而不是 rvalue 和 lvalue?
【发布时间】:2019-06-21 15:34:02
【问题描述】:

所以我想练习std::forward 的用法,并创建了一个带有2 个构造函数的Test 类。 1 个带有T&,另一个带有T&& 过载。 T& 打印 lvalueT&& 打印 rvalue 所以我知道使用了哪个构造函数。我在堆栈上创建了 2 个类实例,令我惊讶的是,它们都使用了 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。我做错了什么?

【问题讨论】:

  • auto 绝不是参考。

标签: c++ forward rvalue lvalue stdmove


【解决方案1】:

您的问题源于forward 的返回类型。您使用auto 作为返回类型,它不会为您推断出引用。这意味着当你返回时,无论它从哪个分支返回,你都是按值返回,这意味着你有一个prvalue。

您需要的是decltype(auto),因此您返回一个右值或左值引用,具体取决于返回语句。使用

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

【讨论】:

  • 难道没有auto&amp;这样的东西,还是我在编造愚蠢?
  • @Chipster 有,但它总是会返回一个左值引用,这不是您在转发函数中想要的。
  • @3l4x 不客气。顺便说一句,很好的第一次努力。通用代码和转发可能很难正确处理。
  • @NathanOliver,即使对于编译器也是如此。 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
相关资源
最近更新 更多