正在使用std :: vector&lt; std :: shared_ptr <const t =“”>&gt;反模式?</const>

时间:2014-06-06 15:50:18

标签: c++ templates c++11 c++-standard-library

很长一段时间我一直在使用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

所以每次我想成为一个const正确并写一个函数,如:

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> >

  4. 的想法

    1.问题是计算开销和代码增加的丑陋,而2.给代码一个&#34;一切都是模板&#34;风味。

    我是一名经验不足的程序员,我不想走向错误的方向。我想听听有这个问题经验的人的意见。

4 个答案:

答案 0 :(得分:20)

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

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

  1. 按值存储对象。
  2. 按值将多个对象存储在容器中。
  3. 如果没有其他工作,请使用智能指针。
  4. 请参阅Bjarne Stroustrup - The Essence of C++: With Examples in C++84, C++98, C++11, and C++14 0:37:40。

答案 1 :(得分:8)

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>>只有在对象没有所有者的情况下才是合理的。

答案 2 :(得分:2)

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

答案 3 :(得分:1)

如果您坚持保留std::vector,可以尝试将其封装到句柄体成语结构中。

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