【问题标题】:Std::forward and template type deductionstd::forward 和模板类型推导
【发布时间】:2017-11-25 17:36:58
【问题描述】:

我编写了以下小程序来了解 std::forward 的工作原理。

#include <iostream>
#include <memory>

template<class T>
void foo3(T&& bar){
    std::cout<<"foo3&&"<<std::endl;
}

template<class T>
void foo3(T& bar){
    std::cout<<"foo3&"<<std::endl;
}

template<class T>
void foo(T&& bar){
    std::cout<<"foo&&"<<std::endl;
    foo3(std::forward<T>(bar));
}

template<class T>
void foo(T& bar){
    std::cout<<"foo&"<<std::endl;
    foo3(std::forward<T>(bar));
}

int main(int argc, char * argv []){
    int i = 1;
    foo(2);
    foo(i);
    return 0;
}

我希望得到以下输出:

"foo&&"
"foo3&&"
"foo&"
"foo3&"

但是,我得到以下结果,我无法解释:

"foo&&"
"foo3&&"
"foo&"
"foo3&&"

因此,如果 foo 使用左值调用,我希望 foo 将转发左值并调用 foo3 的左值版本。但是一直调用 foo3(T&&) 。我是否对 std::forward 的工作方式完全理解错误,还是有一个微妙的错误?或者更糟糕的是,代码是否应该像我预期的那样工作,也许我搞砸了我的编译器实现? 顺便说一句。我正在使用 g++ 7.2

【问题讨论】:

  • std::forward 用于转发引用,T&amp; 不是。

标签: c++ forward forwarding-reference


【解决方案1】:

我是否理解 std::forward 的工作原理完全错误

是的。 std::forward 用于转发引用,而void foo(T&amp;) 中的bar 则不是。如果你不尊重这一点,你会得到一些奇怪的行为。

要了解为什么您需要了解 std::forward 的实际作用。这只是一个演员表

static_cast<T&&>(t)

其中tstd::forward 的参数。所以,foo 的最终调用如下所示:

std::cout<<"foo&"<<std::endl;
foo3(std::forward<int>(bar));

T 被推导出为 int,如果查看转换,您会发现它将 bar 转换为右值引用,而不是像您预期的那样的左值引用。

【讨论】:

  • 当应用于前向引用时,我会将std::forward 描述为条件转换
  • 啊,当然。就这么简单,我觉得有问题。 std::forward(bar) 应该按预期工作。
  • @Hatatister 嗯,是的。但我认为这是一个棘手的解决方法。最好不要在不是转发引用的变量上使用std::forward
  • @Rakete1111 我只在 lvalue_reference 上使用 forward 来了解 std::forward 如何在边缘情况下工作。我写了这个例子来查找程序中的一个错误,我在其中使用了转发引用和 std::forward ...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 2012-09-08
相关资源
最近更新 更多