首页 > 后端开发 > C++ > 为什么 std::forward 使用恒等模板来禁用模板参数推导?

为什么 std::forward 使用恒等模板来禁用模板参数推导?

Susan Sarandon
发布: 2024-11-09 09:34:02
原创
700 人浏览过

Why does std::forward use the identity template to disable template argument deduction?

禁用 std::forward 的模板参数推导以确保正确转发

考虑 VS2010 中 std::forward 的定义:

<code class="cpp">template<class _Ty> inline
_Ty&amp;&amp; forward(typename identity<_Ty>::type&amp; _Arg)
{   // forward _Arg, given explicitly specified type parameter
    return ((_Ty&amp;&amp;)_Arg);
}</code>
登录后复制

身份模板的目的是禁用模板参数推导。为什么这在这种情况下至关重要?

模板参数推导会导致错误的类型推导。如果对类型 X 的对象的右值引用传递给参数类型为 T& 的模板函数,则模板实参推导会将 T 推断为 X,从而产生参数类型 X&。然而,对于完美转发,参数是左值,因为它有名称。因此,在 std::forward 中使用模板参数推导将导致推导的参数类型成为左值引用或 const 左值引用。

<code class="cpp">template<typename T>
T&amp;&amp; forward_with_deduction(T&amp;&amp; obj)
{
    return static_cast<T&amp;&amp;>(obj);
}</code>
登录后复制

考虑以下示例:

<code class="cpp">void test(int&amp;){}
void test(const int&amp;){}
void test(int&amp;&amp;){}

template<typename T>
void perfect_forwarder(T&amp;&amp; obj)
{
    test(forward_with_deduction(obj));
}

int main()
{
    int x;
    const int&amp; y(x);
    int&amp;&amp; z = std::move(x);

    test(forward_with_deduction(7));    //  7 is an int&amp;&amp;, correctly calls test(int&amp;&amp;)
    test(forward_with_deduction(z));    //  z is treated as an int&amp;, calls test(int&amp;)

    //  All the below call test(int&amp;) or test(const int&amp;) because in perfect_forwarder 'obj' is treated as
    //  an int&amp; or const int&amp; (because it is named) so T in forward_with_deduction is deduced as int&amp; 
    //  or const int&amp;. The T&amp;&amp; in static_cast<T&amp;&amp;>(obj) then collapses to int&amp; or const int&amp; - which is not what 
    //  we want in the bottom two cases.
    perfect_forwarder(x);           
    perfect_forwarder(y);           
    perfect_forwarder(std::move(x));
    perfect_forwarder(std::move(y));
}</code>
登录后复制

在此示例中,完美转发失败,因为 Perfect_forwarder 中的参数因其名称而被视为左值或 const 左值引用。这会导致forward_with_deduction中的类型推导不正确,从而产生不需要的static_cast语义。

在std::forward中禁用带有身份模板的模板参数推导可确保std::forward始终返回右值引用,这对于正确完美转发左值和右值。

以上是为什么 std::forward 使用恒等模板来禁用模板参数推导?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板