很长一段时间我一直在使用std::vector
和std::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> >;
问题在于虽然SharedPtrVector
和SharedConstPtrVector
非常相似,但SharedConstPtrVector
无法转换为SharedPtrVector
。
所以每次我想成为一个const正确并写一个函数,如:
void f(const SharedConstPtrVector<T>& vec);
我无法将const SharedPtrVector<T>
传递给f
。
我在考虑这个问题并考虑了几个选择:
编写转换函数
template <typename T>
SharedConstPtrVector<T> toConst(const SharedPtrVector<T>&);
以通用形式编写代码:
template <typename T>
void f(const std::vector< std::shared_ptr<T> >& vec);
或
template <typename TIterator>
void f(TIterator begin, TIterator end);
放弃std::vector< std::shared_ptr<const T> >
1.问题是计算开销和代码增加的丑陋,而2.给代码一个&#34;一切都是模板&#34;风味。
我是一名经验不足的程序员,我不想走向错误的方向。我想听听有这个问题经验的人的意见。
答案 0 :(得分:20)
我建议您检查一下您的设计,以便建立这些对象的明确所有者。这是缺乏明确的所有权,导致人们使用共享的智能指针。
Bjarne Stroustrup建议仅使用智能指针作为最后的手段。他的建议(最好到最差)是:
请参阅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
共享指针。