【问题标题】:How does the compiler know that which overload of std::forward function has to be called?编译器如何知道必须调用 std::forward 函数的哪个重载?
【发布时间】:2014-08-22 10:09:40
【问题描述】:

以下签名被声明为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);

那么这就是编译器使用T = int&amp; 实例化foo_as_always 的方式:

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);

然后编译器用T = int实例化foo_as_always

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

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

【问题讨论】:

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


【解决方案1】:

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

在调用foo_as_always(i); 中,i 是一个左值,因此T 被推导出为int &amp;,这就是您提供给std::forward 的内容。

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

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

【讨论】:

    猜你喜欢
    • 2020-04-15
    • 1970-01-01
    • 2010-09-17
    • 2015-11-30
    • 2016-10-01
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多