【发布时间】:2015-07-10 16:14:28
【问题描述】:
问题:
假设一个函数
void doFoo(const std::vector<std::reference_wrapper<DataT> >& data);
其中DataT 是一些保存一些数据的类型。我用std::vector作为容器类的典型例子。
您认为用std::vector<DataT> 调用上述函数最优雅的方式是什么?
背景:
在函数doFoo(...) 内部,我不想拥有数据的所有权。因此,我不想使用std::shared_ptr 或std::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> >,因为类型完全不相关。
可能的解决方案:
- 在调用函数之前创建一个
std::vector<std::reference_wrapper<DataT> >,并用对dataVec中所有元素的引用填充它。
缺点:我必须为每个函数调用重新打包。 - 重载
doFoo(...)以获取std::vector<DataT>并在那里进行重新打包。
缺点:如果我在很多地方使用这个概念,它会创建相当多的样板代码。此外,对我来说,调用额外的函数似乎有点多余,甚至可能令人困惑。 - 启用从
std::vector<DataT>到std::vector<std::reference_wrapper<DataT> >的一些隐式转换。但我不知道这是否可能,以及是否会产生一些不好的后果。如果这个或类似的东西是可能的和安全的,我会更喜欢这个解决方案。
【问题讨论】:
-
“如果我只使用对 std::vector
的引用,我可能必须复制几个 DataT 来为函数调用创建向量”。不是这样 - 使用 const std::vector<DataT>& data不会对其绑定的向量的内部状态进行任何复制。 -
@Alejandro 我读了他的问题评论说他可能有一些不在向量中的 DataT 对象,他想对它们调用 doFoo 。他不想为了调用 doFoo 将它们复制到向量中
-
抱歉不清楚:我的意思是当我已经有了数据,但它们没有打包到
std::vector<DataT>中,或者即使我有一个该类型的对象但只想使用作为数据的子集,我必须创建一个新的std::vector<DataT>并通过复制数据来填充它,然后才能真正调用该函数。 (谢谢,@pythonicmetaphor,我在看到你之前写了我的评论。) -
doFoo是否需要该签名?我认为std::vector<DataT*>比使用reference_wrapper更简单,DataT*完美地表达了对您不拥有的东西的引用。如果更改doFoo是可能的,那么另一种选择是将其更改为采用一对迭代器,这样您就可以更灵活地传递给它,并且不必构造完全正确类型的容器。 -
即我质疑你一开始就设置的前提:“假设一个函数” ...为什么假设一个看起来很奇怪的函数?
标签: c++ c++11 containers reference-wrapper