繁体   English   中英

正在使用 std::vector&lt; std::shared_ptr<const T> &gt; 反模式?

[英]Is using std::vector< std::shared_ptr<const T> > an antipattern?

很长一段时间我都在使用std::vectorstd::shared_ptr 最近,每当需要指向 const 对象的指针时,我就开始使用std::shared_ptr<const T> 这一切都可以,因为std::shared_ptr<T>可以转换为std::shared_ptr<const T> ,然后它们共享相同的引用计数器,一切都感觉很自然。

但是当我尝试使用诸如std::vector< std::shared_ptr<const T> >构造时,我遇到了麻烦。 为简化起见,我将表示两种结构:

template <class T>
using SharedPtrVector = std::vector< std::shared_ptr<T> >;

template <class T>
using SharedConstPtrVector = std::vector< std::shared_ptr<const T> >;

问题是,虽然SharedPtrVectorSharedConstPtrVector非常相似,但SharedConstPtrVector不能转换为SharedPtrVector

所以每次我想成为一个正确的常量并编写一个函数,例如:

void f(const SharedConstPtrVector<T>& vec);

我无法将 const SharedPtrVector<T>传递给f

我想了很多,并考虑了几种选择:

  1. 编写转换函数

    template <typename T> SharedConstPtrVector<T> toConst(const SharedPtrVector<T>&);
  2. 以通用形式编写代码:

     template <typename T> void f(const std::vector< std::shared_ptr<T> >& vec);

    或者

    template <typename TIterator> void f(TIterator begin, TIterator end);
  3. 放弃std::vector< std::shared_ptr<const T> >的想法

1. 的问题是计算开销和代码丑陋程度的增加,而 2. 给代码带来了“一切都是模板”的味道。

我是一个没有经验的程序员,我不想走错方向。 我想听听有此问题经验的人的建议。

我建议您查看您的设计,以便建立这些对象的明确所有者。 这是缺乏明确的所有权,导致人们使用共享智能指针。

Bjarne Stroustrup建议仅使用智能指针作为最后的手段。 他的建议(最好到最差)是:

  1. 按值存储对象。
  2. 按值将许多对象存储在容器中。
  3. 如果没有其他工作,请使用智能指针。

参见Bjarne Stroustrup - C ++的本质:使用C ++ 84,C ++ 98,C ++ 11和C ++ 14中的示例,时间为0:37:40。

1问题与shared_ptr<>无关,但对普通指针已经发生:

template<typename T>
void foo(std::vector<const T*>);

int a,b;
std::vector<int*> bar={&a,&b};
foo<???>(bar);        // no value for ??? works

2构造vector<shared_ptr<T>>只有在没有对象持有者的情况下才是合理的。

它是存储不可变(以及线程安全)对象的有效方式,是每个元素的写时复制缓存的构建块。 绝对不是反模式。

如果你坚持保持std::vector你可以尝试将它封装成一个句柄体成语结构。

这允许您在const句柄中保留非const共享指针。

如果我存储了数千个 3d 点(例如在 std::vector 中)并且想要将这些条目的地址推送到另一个结构中(比如用于排序或其他目的的堆),并且二级结构可能需要删除其中的一些条目(例如,值比传感器规定的准确度更接近),谁是“所有者”? 似乎最好的解决方案是智能指针向量,究竟 Stroustrup 建议应该是最后的手段,点本身分配在堆上?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM