为什么在std::auto_ptr上不允许使用运算符[]?

3
为什么std::auto_ptr不允许使用operator []?
#include <iostream>

using namespace std ;

template <typename T>
void foo( T capacity )
{
    auto_ptr<T> temp = new T[capacity];

    for( size_t i=0; i<capacity; ++i )
        temp[i] = i; // Error
}

int main()
{
    foo<int>(5);
    return 0;
}

使用Microsoft Visual C++ 2010编译。

错误:错误C2676:二进制“[”:'std::auto_ptr<_Ty>'未定义此运算符或无法转换为预定义运算符可接受的类型。


可能是C++ auto_ptr for arrays的重复问题。 - fbrereto
顺便提一下,capacity的参数类型应该选择与T不同的类型。 - fbrereto
你能详细说明为什么 std::vector<T> 不能满足你的需求吗? - fbrereto
@fbrereto - 正在学习std :: auto_ptr。但是遇到了一个令人惊讶的错误。这只是一个学习的过程。 - Mahesh
请注意,在C++0x中,std::unique_ptrstd::auto_ptr的更优秀替代品)被专门用于数组类型。 - GManNickG
4个回答

11
原因是auto_ptr会使用delete而不是delete[]释放内容,所以auto_ptr不适合处理堆分配的数组(使用new[]构造),只适合处理使用new构造的单个堆分配数组。
支持operator[]将鼓励开发人员将其用于数组,并错误地给出类型可以支持数组的印象,而事实上它不能。
如果您想要类似于智能指针的数组类,请使用boost::scoped_array

1
@Mahesh:是的——它被称为std::vector。尽管名称如此,但它本质上是对象数组的智能指针。 - Jerry Coffin
@Jerry:嘿,与其他任何智能指针不同的是,它在赋值时具有克隆语义。天才! - Steve Jessop
@Jerry Coffin - 明白了,谢谢。 (这是针对你之前关于std::vector的评论) - Mahesh
@Jerry:遗憾的是,它没有将克隆语义与运行时多态性结合起来。一个正确的克隆指针相当困难。 - Steve Jessop
@Steve:非常正确——即使如此,我发现向量比大多数人通常认为的智能指针更有用。 - Jerry Coffin
显示剩余2条评论

2
因为 std::auto_ptr 不适用于数组。
此外,在你的示例中。
std::auto_ptr<T> temp = new T(capacity); // T=int, capacity=5

实际上,它只分配了一个 int 并用 capacity 进行初始化。它并没有创建你所期望的整数数组。

我本意使用 []。感谢你指出来。 - Mahesh
@Mahesh:还是有错误。auto_ptr 不兼容数组。使用 new[] 初始化 auto_ptr 会导致未定义的行为。 - Ben Voigt
@Ben Voigt- 你应该把它发布为答案。今天又学到了一点。谢谢 :) - Mahesh

1

auto_ptr 被设计用于持有单个元素的指针;在其销毁时,它将使用 delete(而不是 delete[])。

您的示例并没有做您认为它应该做的事情。或者至少名称 capacity 是误导性的,因为您只分配了一个单独的元素(并将 capacity 的值赋给它)。您的 for 循环没有任何意义。


1

auto_ptr和其他智能指针仅用于存储单个对象的指针。这是因为它们在析构函数中使用delete,而不是delete[],如果它存储指向数组的指针,则需要使用delete[]

如果您需要在智能指针中包装一个对象数组,则标准库没有提供任何帮助。但是,Boost提供了scoped_array,它类似于std::auto_ptr,并且可以容纳由new[]创建的对象数组。


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