为什么没有std::shared_ptr<T[]>的特化版本?

67
标准提供了std::unique_ptr的模板特化,它在析构函数中正确调用delete[]
void func()
{
   std::unique_ptr< int[] > arr(new int[10]);

   .......
}

使用std::shared_ptr时,这种特殊化是不可用的,因此需要提供一个正确调用delete[]的删除器:
void func()
{
    // Usage
    shared_ptr array (new double [256], [](double* arr) { delete [] arr; } ); 

    ..............
}

这只是一个疏忽吗?(就像有一个std::copy_if一样),还是有其他原因?

3
注意:基于 Boost 的工作,有一个新提案建议将此功能添加到 C++17 中,请参见 http://open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3640.html。 - Jonathan Wakely
请注意,在处理数组时,许多shared_ptr机制应该被禁用,例如引用子对象的能力。 - Ben Voigt
1个回答

72
LWG(C++委员会的库工作组)曾经简要考虑过这种可能性,但这个想法并不是没有争议。尽管争议主要是关于添加到shared_ptr<T[]>提案中的一个功能的(在shared_ptr<T[]>上进行算术运算),但它仍然存在争议。

但最终真正的原因是,尽管有讨论,但LWG从未收到任何实际的书面提案。它从未成为任何人的优先事项清单(包括我自己),足以花时间撰写提案。

最近,一些LWG成员之间开始就这个话题进行非正式交流,并且我已经亲自进行了原型设计。但仍然没有书面提案。我认为这将是工具箱中不错的附加工具。它是否真正发生还是任何人的猜测。

更新

shared_ptr的数组支持现在已经有了草案TS:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4077.html

更新(2017年)

现在C++17已经支持此功能。请参见shared_ptr::shared_ptr()的第3种情况。


2
我看到的第一个有真正答案的“为什么没有……”问题,还有动态分配数组?使用vector和std::array,真的看不出需要(?) - Nim
13
@Nim: 如果对开销极为敏感,则使用 std::unique_ptr<T[]>(已存在)是不错的选择。与 vector<T> 不同,unique_ptr<T[]> 不包括容量或大小的开销。客户端可能需要增加外部开销来存储大小信息,但如果永远不改变数组大小,则无需增加容量开销。但这并不意味着 unique_ptr<T[]>vector<T> 更好。实际上,我认为前者的使用情况相对于后者来说会比较稀少。但前者的使用情况并非为零。 - Howard Hinnant
4
类似地,shared_ptr<T[]> 有时可替换 shared_ptr<vector<T>> ,并具有更低的开销。 boost::shared_array<T> 的存在和持续支持说明一些程序员发现这样的工具偶尔很有用。 - Howard Hinnant
7
shared_ptr<T[]> 的好处在于只需要解除引用一次指针即可访问数组的任意元素,而 shared_ptr<vector<T>> 则需要两次解除引用(一次为 shared_ptr,一次为存储在 vector 中的数组)。 - Jeremiah Willcock
2
为什么似乎每个人都忽略了 shared_ptr<std::array<T,N>>?与 shared_ptr<T[]> 相比,有没有任何缺点被我忽视了? - MikeMB
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接