【问题标题】:Why operator [] is not allowed on std::auto_ptr为什么 std::auto_ptr 上不允许使用运算符 []
【发布时间】:2011-07-17 19:29:52
【问题描述】:

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

#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的可能重复
  • 顺便说一下,capacity 的参数类型应该不是T
  • 您能详细说明为什么std::vector&lt;T&gt; 不能满足您的需求吗?
  • @fbrereto - 刚刚学习std::auto_ptr。并对这个错误感到震惊和惊讶。这只是一个学习部分。
  • 请注意,在 C++0x 中,std::unique_ptrstd::auto_ptr 的高级替代品)专门用于数组类型。

标签: c++ visual-c++-2010 auto-ptr


【解决方案1】:

因为std::auto_ptr 不适合与数组一起使用。

此外,在您的示例中

std::auto_ptr<T> temp = new T(capacity); // T=int, capacity=5

实际上分配了一个单个 int 并用capacity 对其进行初始化。它不会像您预期的那样创建整数数组。

【讨论】:

  • 我打算使用[]。感谢收看。
  • @Mahesh:仍然是一个错误。 auto_ptr 与数组不兼容。使用 new[] 初始化 auto_ptr 会导致未定义的行为。
  • @Ben Voigt-您应该将其发布为答案。今天的另一个学习点。谢谢:)
【解决方案2】:

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

如果您需要将对象数组包装在智能指针中,标准库不会提供任何帮助。但是,Boost 确实提供了scoped_array,其行为类似于std::auto_ptr,并用于保存由new[] 创建的对象数组。

【讨论】:

    【解决方案3】:

    因为auto_ptr 旨在保存指向单个元素的指针;它将使用delete(特别是不是delete[])来销毁它。

    您的示例没有做(我认为)您认为的事情。或者至少名称容量具有误导性,因为您只分配一个元素(并将容量值分配给它)。你的 for 循环没有任何意义。

    【讨论】:

      【解决方案4】:

      原因是auto_ptr会使用delete而不是delete[]来释放内容,所以auto_ptr不适合处理堆分配的数组(用new[]构造),只适合处理使用new 构造的单个堆分配数组。

      支持operator[] 会鼓励开发人员将其用于数组,并且会错误地给人以该类型可以支持数组的印象,而实际上它不能。

      如果您想要一个类似智能指针的数组类,请使用boost::scoped_array

      【讨论】:

      • @Michael - 除了使用 boost 库之外,还有其他智能指针可以完成这项工作,在标准头文件中可用。
      • @Mahesh:是的——它叫做std::vector。尽管有这个名字,它本质上是一个对象数组的智能指针。
      • @Jerry:呵呵,与其他任何智能指针不同,它在赋值时具有克隆语义。天才!
      • @Jerry Coffin - 知道了。谢谢。 (这是您之前对 std::vector 的评论)
      • @Jerry:遗憾的是,它没有将克隆语义与运行时多态性结合起来。一个正确的克隆指针是相当困难的。
      猜你喜欢
      • 2012-10-30
      • 1970-01-01
      • 2018-05-17
      • 2017-05-09
      • 1970-01-01
      • 2014-12-03
      • 1970-01-01
      • 2018-07-22
      相关资源
      最近更新 更多