![](/img/trans.png)
[英]Const correctness with std::vector<str::shared_ptr<T>>
[英]Is using std::vector< std::shared_ptr<const T> > an antipattern?
很长一段时间我都在使用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
。
所以每次我想成为一个正确的常量并编写一个函数,例如:
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. 给代码带来了“一切都是模板”的味道。
我是一个没有经验的程序员,我不想走错方向。 我想听听有此问题经验的人的建议。
我建议您查看您的设计,以便建立这些对象的明确所有者。 这是缺乏明确的所有权,导致人们使用共享智能指针。
Bjarne Stroustrup建议仅使用智能指针作为最后的手段。 他的建议(最好到最差)是:
参见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.