这是转发参考

Is this a forwarding reference?

本文关键字:参考 转发      更新时间:2023-10-16

Scott Meyers在此示例中足够清楚了RVALUE参考和转发参考之间的区别:

Widget&& var1 = someWidget;     // here, “&&” means rvalue reference (1)
auto&& var2 = var1;             // here, “&&” does not mean rvalue reference (2)
template<typename T>
void f(std::vector<T>&& param); // here, “&&” means rvalue reference (3)
template<typename T>
void f(T&& param);              // here, “&&”does not mean rvalue reference (4)

本质上,当我们拥有可分解上下文时,这种区别发生在情况下,因此(3)明确指出我们具有vector<...>&&,而将T进行(4),并且在应用参考后进行(4)折叠规则)按"价值类别"分类。

但是,匹配更复杂的模式会发生什么?以以下情况为例:

template <template <class...> class Tuple, class... Ts>
void f(Tuple<Ts...>&& arg)
{
}

&&在这里意味着什么?

在您的上一个示例中, arg是rvalue参考。

a 转发参考是对CV UNqualified模板参数

的RVALUE参考

Tuple<Ts...>不是模板参数。

(引用[temp.deduct.call]。)

它是rvalue参考,而不是转发参考。

最简单的方法是尝试通过lvalue,如果失败,则是rvalue参考,如果不是,则转发参考:

template<typename... Ts>
struct foo {};
//f function definition
int main() {
    foo<int, double> bar;
    f(bar); // fails! Cannot bind lvalue to rvalue reference
    f(foo<int, double>{}); // ok, rvalue is passed
}

概念转发引用不是标准概念,当您看到它时,它很有用,但是如果您想正确理解和处理它,则必须了解参考算术。(我相信迈耶的书也有一章)

转发参考概念背后的是参考算术:

  • &amp;&amp;&amp;&amp;=&amp;&amp;
  • &amp;&amp;&amp;=&amp;
  • &amp;&amp;&amp;=&amp;
  • &amp;&amp;=&amp;

让我们模拟使用转发参考的编译器模板类型扣除

template<class T>
void foo(T&&);
//...
const int i=42;
foo(i); // the compiler will defines T = const int &
         //          T&&  = const int & && = const int &
         // => the compiler instantiates void foo<const int &>(const int &);
foo(6*7);// the compiler will defines T = int
         //          T&&  = int &&
         // the compiler instantiates  void foo<int>(int &&);

在这种情况下,模板的实例化可以产生函数wich通过lvalue参考或获取参数的函数rvalue参考参考:转发参考是根据模板类型扣除,rVALUE参考或LVALUE参考。它是这样命名的,因为在这种情况下,该参数应作为lvalue或xvalue传递,这是T&& std::forward<T>(T&& a)

的工作

如果您声明函数具有:

 template<class T>
 void foo(ATemplateClass<T> && a);

编译器推导的T类型是什么,您都将获得RVALUE参考Paramater。