c++ - 在 std::forward 它如何接受右值?

标签 c++ c++11 perfect-forwarding

查看 Scott Meyer 的 Effective Modern C++ pages 200-201,建议的 std::forward 的简化实现可能是(确实在其他地方看到了正确的实现):

template <typename T>
T&& forward(std::remove_reference_t<T>& param)
{ return static_cast<T&&>(param); }

当接受一个右值 Widget 时,它变成:
Widget&& forward(Widget& param)
{ return static_cast<Widget&&>(param); }

现在,如果您使用该替换代码,然后执行以下操作:
struct Widget { };

Widget&& forward(Widget& param)
{ return static_cast<Widget&&>(param); }

template <typename T>
void G(T&& uref)
{ }

template <typename T>
void F(T&& uref)
{ G(forward(uref)); }

int main()
{
  Widget x;
  F(std::move(x));
}

我无法理解并且还没有看到关于 SO 的直接答案是:在 forward 中参数Widget& param如何设法接受Widget&&从 F()?通常 gcc-5.0 会像这样提示非模板代码:

error: invalid initialization of non-const reference of type ‘Widget&’ from an rvalue of type ‘std::remove_reference::type {aka Widget}’



(Question #27501400 几乎触及了这个话题,但并不完全。它显示标准同时具有左值 & 和右值 && 版本。)

最佳答案

"Named rvalue references are lvalues",



所以示例工作正常,如评论中所述。

尽管如此,您的代码可以修改为
template <typename T>
void F(T && uref)
{
    G(forward(move(uref)));
}

被另一个重载(比较)接受:
template<typename T>
T && forward(typename std::remove_reference<T>::type & t)
{
    return static_cast<T &&>(t);
}


template<typename T>
T && forward(typename std::remove_reference<T>::type && t)
{
    static_assert(!std::is_lvalue_reference<T>::value, "T is an lvalue reference");
    return static_cast<T &&>(t);
}

第二个重载将用于右值。如果 T 则有效是 WidgetWidget &&并且 Widget & 的断言失败.

关于c++ - 在 std::forward 它如何接受右值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29041246/

相关文章:

c++ - 完美转发和 std::forward<T> 的使用

c++ - 重新排序可变参数

c++ - 使用 move 语义和完美转发实现 'lazy'运算符+

c++ - 打印伪多维数组时出现问题

c++ - 将服务器响应(std::string)转换为 png 文件

c++ - 带引用计数的无锁堆栈

c++ - 我的对象在 vector 中的地址发生变化

c++ - 为 float 据类型赋值会导致程序崩溃

c++ - 使用g++编译c和c++文件

c++11 - std::atomic_flag 和 std::lock_guard