6

以下签名被声明为std::forward重载:

template<class T> T&& forward(typename remove_reference<T>::type& arg) noexcept;
template<class T> T&& forward(typename remove_reference<T>::type&& arg) noexcept;

现在,考虑以下模板函数:

template<class T> T&& foo_as_always(T&& t)
{
    return std::forward<T>(t);
}

如果我写:

int i = 0;
foo_as_always(i);

然后这就是编译器实例化foo_as_always的方式T = int&

int& foo_as_always(int& t)
{
    // Does it call the first signature of std::forward(int&)
    return std::forward<int&>(t);
}

如果我写:

foo_as_always(0);

然后编译器实例foo_as_alwaysT = int

int&& foo_as_always(int&& t)
{
    // Does it call the second signature of std::forward(int&&)?
    return std::forward<int>(t);
}

在这两种情况下,t变量在任何表达式中都是左值。编译器如何知道std::forward必须调用函数的哪个重载?

4

1 回答 1

6

因为您明确提供了模板参数(您提供了<T>);没有类型扣除。

在调用foo_as_always(i);中,i是一个左值,所以T被推导出来int &,这就是你提供给的std::forward

在调用foo_as_always(0);中,0是一个右值,因此T被推导出来int,这又是你提供给的std::forward

在这两种情况下,它最终都会调用第一个重载,当然t,正如你所说,因为它是一个左值。但是返回类型不同 - 在第一种情况下,它是int& &&, 所以int&,在第二种情况下,它是int &&.

于 2014-08-22T10:18:08.117 回答