【发布时间】:2013-03-21 13:50:25
【问题描述】:
如果我有boost::shared_array<T>(或boost::shared_ptr<T[]>),有没有办法获得与数组共享的boost::shared_ptr<T>?
例如,我可能想写:
shared_array<int> array(new int[10]);
shared_ptr<int> element = &array[2];
我知道我不能使用&array[2],因为它只有int * 类型,而shared_ptr<int> 有一个采用该类型的隐式构造函数会很危险。理想情况下,shared_array<int> 会有一个实例方法,例如:
shared_ptr<int> element = array.shared_ptr_to(2);
很遗憾,我找不到这样的东西。 shared_ptr<int> 上有一个别名构造函数,它将与另一个 shared_ptr<T> 别名,但它不允许使用 shared_array<T> 别名;所以我也不能写这个(它不会编译):
shared_ptr<int> element(array, &array[2]);
//Can't convert 'array' from shared_array<int> to shared_ptr<int>
我使用的另一个选项是使用std::shared_ptr<T>(std 而不是boost)。 T[] 的专业化没有标准化,所以我想自己定义。不幸的是,我认为这实际上不可能以不破坏别名构造函数内部的方式实现,因为它试图将我的std::shared_ptr<T[]> 转换为它自己的特定于实现的超类型,这不再可能。 (我的目前只是从 boost 继承。)这个想法的好处是我可以实现我的实例 shared_ptr_to 方法。
这是我尝试过的另一个想法,但我认为它的效率不足以作为我们可能会在整个大型项目中使用的东西。
template<typename T>
boost::shared_ptr<T> GetElementPtr(const boost::shared_array<T> &array, size_t index) {
//This deleter works by holding on to the underlying array until the deleter itself is deleted.
struct {
boost::shared_array<T> array;
void operator()(T *) {} //No action required here.
} deleter = { array };
return shared_ptr<T>(&array[index], deleter);
}
接下来我要尝试升级到 Boost 1.53.0(我们目前只有 1.50.0),使用 shared_ptr<T[]> 而不是 shared_array<T>,并且始终使用 boost 而不是 @987654344 @(即使对于非数组)。我希望这会起作用,但我还没有机会尝试:
shared_ptr<int[]> array(new int[10]);
shared_ptr<int> element(array, &array[2]);
当然我还是更喜欢实例方法语法,但我想我对那个不走运(没有修改 Boost):
shared_ptr<int> element = array.shared_ptr_to(2);
其他人有什么想法吗?
【问题讨论】:
-
您的删除器想法是应该完成的方式。它没有什么特别低效的(如果有疑问,请使用分析器进行实验)。
-
@n.m.我认为它会创建一个新的控制块(在堆上)供新的
shared_ptr参考。诚然,它并没有那么糟糕,但如果它可以共享同一个控制块,那就更好了。 :) -
您需要
shared_array吗?如果你有一个shared_ptr<T>(带有适当的删除器),你可以使用别名构造函数。 -
从那以后我就想到了这一点。唯一缺少的是
operator[]。我会发布一个答案,说明我最后做了什么。
标签: c++ boost c++11 shared-ptr