0

我编写了以下小程序来了解 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

4

1 回答 1

4

我是否对 std::forward 的工作方式完全理解错误

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

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

static_cast<T&&>(t)

t的论据在哪里std::forward。所以,最终的调用foo看起来像这样:

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

T推断为int,如果查看强制转换,您会发现它强制转换bar为右值引用,而不是您预期的左值引用。

于 2017-11-25T17:45:48.007 回答