【问题标题】:Variadic Templates and RValue refs可变参数模板和 RValue 参考
【发布时间】:2020-04-06 23:33:45
【问题描述】:

考虑以下 C++ 代码

template <class... Args>
void f (const int x, const int y, Args&&... args) {
  // Do something
}

据我了解,这里的Args 可以是左值也可以是右值引用,具体取决于编译时的类型推导。

所以,我应该可以使用 -

调用该函数
float x = 40.0;
f<int, float, double>(10, 20, 30, x, 50.0);

这给了我一个错误,说它无法将 x 从类型 float 转换为类型 float&amp;&amp;

如何使用同时接受左值和右值引用的可变参数模板定义函数。

【问题讨论】:

    标签: c++ c++11 variadic-templates lvalue rvalue


    【解决方案1】:

    据我了解,这里的Args 可以是左值或右值引用,具体取决于编译时的类型推导。

    你说对了一半。 Args&amp;&amp; 将是左值或右值引用。但Args 本身要么是左值引用,要么不是引用。一个更简单的例子:

    template <typename T> void foo(T&& ) { }
    
    foo(1); // T is int
    int x;
    foo(x); // T is int&
    

    当您为x 指定float 时,您指定该特定参数的类型为float&amp;&amp;,并且您不能将左值float 隐式转换为右值。你将不得不投射它(通过std::move):

    f<int, float, double>(10, 20, 30, std::move(x), 50.0);
    

    或者通过float&amp;指定它是一个左值:

    f<int, float&, double>(10, 20, 30, x, 50.0);
    

    或者干脆让演绎去做:

    f(10, 20, 30, x, 50.0);
    

    【讨论】:

    • 简单的推论给出了一个错误,说........file.h:41:87: note: cannot convert ‘x’ (type ‘float’) to type ‘float&amp;&amp;’。我用模板修正了错字...
    • @subzero 不完全符合您问题中的功能,它不会。
    【解决方案2】:

    如果你指定参数,你必须给出左值引用:

    f<int, float&, double>(10, 20, 30, x, 50.0);
    

    或者干脆让编译器为你推断

    f(10, 20, 30, x, 50.0);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-01
      • 2015-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-17
      • 1970-01-01
      相关资源
      最近更新 更多