首页 > 解决方案 > 转发引用的折叠

问题描述

给定代码

struct S{};

template <typename T>
auto foo(T&& t)
{
    static_assert(std::is_same_v<T, std::remove_cvref_t<T>>);
}

void test()
{
    const S s;
    foo(s);  // error

    foo(S{});

    S s2;
    foo(s2); // error
}

T将被推断为

  1. S const&
  2. S
  3. S&

为什么T不推断为

  1. S const
  2. S
  3. S

为什么T在左值情况下保留引用而不是在右值情况下?

操场

标签: c++c++20

解决方案


转发引用的怪癖之一是您永远不会“只有一个值”。

T被推断为S时,这只是因为函数实际上是在接受S&&

当您传递局部变量时,类型推导会识别出这些是左值,因此会将它们绑定到常规引用。一个const在的情况下const S s。函数签名“更改”以反映这一点。

根据参考折叠的规则,您将拥有(const S&)&&标准规定的折叠为 justconst S&的 ,然后您将拥有(S&)&&折叠为 just的 。S&

参考[dcl.ref]

亲眼看看(现场演示)


推荐阅读