【问题标题】:How to forward packed variadic arguments如何转发打包的可变参数
【发布时间】:2021-01-24 07:59:20
【问题描述】:

我有一个函数可以接受打包到元组中的可变参数

template <class... Args>
void Bottom(tuple<Args&&...> t)
{
}

Args&amp;&amp; 是转发引用吗? IE。引用折叠的规则是否适用,还是我只是将 && 附加到包中的每个参数?

假设我想从一个肯定会获得转发引用的函数中调用这个函数:

template <class... Args>
void Top(Args&&... args) {
  // 1. Bottom<Pack...>();
  // 2. Bottom<Pack&&...>();
}

如果我不想更改参数 1 或 2,哪种语法最好?

编辑

我只是使用元组来展示一个包含我的参数的类。实际的打包类在调用层次结构的不同级别上有所不同。使用 using_fwd_as_tuple 的想法很酷,可以作为一种资源来查找库在这种情况下的作用。

【问题讨论】:

  • 如果你问的问题不是你想问的问题,也许打开另一个问题。特别是在你得到答案之后,按照以下方式进行编辑是不好的:“哦,这个问题有一个答案,但我想要一个不同的答案”(我夸大了)

标签: c++ variadic-templates perfect-forwarding forwarding-reference


【解决方案1】:

我会说没有。我会使用std::forward_as_tuple 并让编译器进行推断:

template <class... Args>
void Top(Args&&... args) {
  Bottom(std::forward_as_tuple(args...));
}

【讨论】:

  • +1 因为我可以看到 tuple 的作用并模仿它。不幸的是,我的代码中没有元组。
  • Forward as tuple 创建一个对参数的引用(左值或右值引用)的元组。我特别想保持Top 函数推导出的初始类型
【解决方案2】:

不,tuple&lt;Args&amp;&amp;...&gt; t 不是转发引用。它们只能作为顶级参数出现。

您没有附加任何内容,您正在尝试匹配参数。此类函数仅接受包含 r 值引用的元组(按值)。

示例

#include <tuple>
using namespace std;

template <class... Args>
void Bottom(tuple<Args&&...> t)
{
}

// Type your code here, or load an example.
int main(){
    double var=0.0;

    tuple<int,double&,char&&> tup1{1,var,'c'};
    //#1
    //Bottom(tup1);

    tuple<int&&,double&&,char&&> tup2{1,0.0,'c'};
    //#2
    //Bottom(tup2);
    //#3
    Bottom(std::move(tup2));
}
  1. 由于参数无法匹配,因此无法编译。
  2. 也不编译。尽管参数确实匹配,但元组本身是按值传递的,在这种情况下是通过副本传递的,并且复制构造函数在存在 r 值元组成员的情况下被删除。
  3. 移动没问题,这会实例化这个模板:
    template<>
    void Bottom<int, double, char>(std::tuple<int &&, double &&, char &&> t)
    {
    }
    

【讨论】:

    猜你喜欢
    • 2016-06-25
    • 2017-04-25
    • 2014-07-25
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-22
    相关资源
    最近更新 更多