我应该如何将容器转换为reference_wrappers的容器?

时间:2015-07-10 16:14:28

标签: c++ c++11 containers reference-wrapper

问题:

假设一个功能

void doFoo(const std::vector<std::reference_wrapper<DataT> >& data);

其中DataT是某种类型,包含一些数据。我使用std::vector作为容器类的典型示例。

您认为使用std::vector<DataT>调用上述函数的最优雅方式是什么?

背景

在函数doFoo(...)内部,我不想取得数据的所有权。因此,我不想使用std::shared_ptrstd::unique_ptr。据我了解,正确的方法是使用参考。如果我只使用对std::vector<DataT>的引用,我可能需要复制几个DataT来为函数调用创建向量,以防我没有直接在std::vector<DataT>中构造数据。因此,std::vector<std::reference_wrapper<DataT> >似乎是最佳解决方案。

如果我只有一个DataT对象(让我们称之为data1),我可以通过调用doFoo({data1})轻松地将其放入函数中,并且正确的向量将是隐含地构建。但是,如果我已经有std::vector<DataT> dataVec并尝试调用doFoo(dataVec),则不会将其隐式转换为std::vector<std::reference_wrapper<DataT> >,因为这些类型完全不相关。

可能的解决方案:

  1. 在调用函数之前创建一个std::vector<std::reference_wrapper<DataT> >,并用dataVec中所有元素的引用填充它。
    缺点:我必须为每个函数调用重新打包。
  2. 重载doFoo(...)以取std::vector<DataT>并在那里重新打包。
    缺点:如果我在很多地方使用这个概念,它会创建一些样板代码。另外,对我来说,似乎有点多余,甚至可能会因为额外的函数调用而感到困惑。
  3. 启用从std::vector<DataT>std::vector<std::reference_wrapper<DataT> >的隐式转化。但我不知道这是否可行,以及是否会产生一些不良后果。如果这种或类似的东西是可能和安全的,我宁愿这个解决方案。

1 个答案:

答案 0 :(得分:1)

我在这里看到了一些选择。

<强> 1。使用向量的迭代器构造函数。

std::vector<DataT> x;
doFoo({x.begin(), x.end()});

应该从向量构造一个引用包装器的向量,因为迭代器无论如何都引用了对象。

<强> 2。使用std::vector<DataT> const &作为doFoo参数,并将数据移至矢量中。

如果您的数据位于某处,则可以将它们移动到矢量中而不是复制(如果移动DataT有意义的话)。

DataT d1, d2, d3;
std::vector<DataT> v { std::move(d1), std::move(d2), std::move(d3) };
dooFoo(v);

将所有权转移到向量(但不转移到函数)!

第3。如果有多个要处理的话,通常会在向量中对DataT进行操作。

如果你周围没有多个DataT对象需要复制到向量中,则不需要reference_wrapper。