3

Why operator [] is not allowed on 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;
}

Compiled on Microsoft Visual C++ 2010.

Error: error C2676: binary '[' : 'std::auto_ptr<_Ty>' does not define this operator or a conversion to a type acceptable to the predefined operator

ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
Mahesh
  • 34,573
  • 20
  • 89
  • 115

4 Answers4

11

The reason is that auto_ptr will free the content using delete instead of delete[], and so auto_ptr is not suitable for handling heap-allocated arrays (constructed with new[]) and is only suitable for handling single, heap-allocated arrays that were constructed with new.

Supporting operator[] would encourage developers to use it for arrays and would mistakenly give the impression that the type can support arrays when, in fact, it cannot.

If you want a smartpointer-like array class, use boost::scoped_array.

Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
  • @Michael - Other than using `boost` library, is there any other smart pointer that can do this job, available in standard headers. – Mahesh Mar 17 '11 at 23:18
  • 1
    @Mahesh: yes -- it's called `std::vector`. Despite the name, it's fundamentally a smart pointer for an array of objects. – Jerry Coffin Mar 17 '11 at 23:23
  • @Jerry: heh, and unlike any of the other smart pointers it has clone semantics on assignment. Genius! – Steve Jessop Mar 17 '11 at 23:32
  • @Jerry Coffin - Got you. Thanks. ( This is for your previous comment on std::vector ) – Mahesh Mar 17 '11 at 23:33
  • @Jerry: sadly it falls short of combining clone semantics with runtime polymorphism, though. A proper clone pointer is quite hard. – Steve Jessop Mar 17 '11 at 23:35
  • @Steve: quite true -- even so, I find vector much more useful that most of what people usually think of as smart pointers. – Jerry Coffin Mar 17 '11 at 23:42
  • @Jerry: Me too. But then I don't very often share object-ownership, and I return by value until proven otherwise, so much of the time dynamic polymorphism is the only thing smart pointers are *for*. I don't think I've ever used `scoped_array` in anger. – Steve Jessop Mar 17 '11 at 23:49
2

Because std::auto_ptr is not intended to be used with arrays.

Besides, In your sample

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

actually allocates a single int and initializes it with capacity. It does not create an array of integers as you seem to have intended.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
1

Because auto_ptr is designed to hold a pointer to a single element; it will use delete (specifically not delete[]) on its destruction.

Your example is not doing what (I think) you think it does. Or at least the name capacity is misleading, because you are only allocating a single element (and assigning the value of capacity` to it). Your for loop has no sensible meaning.

eq-
  • 9,986
  • 36
  • 38
1

auto_ptr and other smart pointers are only intended to store a pointer to a single object. This is because they use delete in the destructor, rather than delete[], which would be needed if it were storing a pointer to an array.

If you need to wrap an array of objects in a smart pointer, the standard library doesn't offer anything to help. However, Boost does offer scoped_array, which behaves similar to std::auto_ptr and is made to hold arrays of objects created by new[].

Collin Dauphinee
  • 13,664
  • 1
  • 40
  • 71