Search code examples
c++raiiauto-ptr

Initializing std::auto_ptr: "error: no match for call to ‘(std::auto_ptr<int>) (int*)’"


I'm having trouble using std::auto_ptr. I try to compile the following on Ubuntu 11.10 using GCC 4.6.1, and I get the error message error: no match for call to ‘(std::auto_ptr<int>) (int*)’.

#include <memory>
#include <iostream>

class Toy  {

public:
    std::auto_ptr<int> foo;

    Toy() {
        foo(new int(3));
    }
};

int main() {

    Toy toy;

    std::cout << *toy.foo << std::endl;

    return 0;
}

I was pretty sure a std::auto_ptr< T > takes in a T* as its constructor arguments, but apparently not... My apologies if this is a trivial or duplicate question, but I searched the archives, and haven't found an answer. Places like this seem to suggest that the above code should work. Anyway, any help would be appreciated!


Solution

  • To initialize the fields of a class you use the initialization list syntax:

    class Toy  {
    
    public:
        std::auto_ptr<int> line;
    
        Toy() : line(new int(3))
        {
    
        }
    };
    

    otherwise, you may get a default-initialized line and reseat it with its reset method:

    class Toy  {
    
    public:
        std::auto_ptr<int> line;
    
        Toy()
        {
            line.reset(new int(3));
        }
    };
    

    But there are more problems with this code; first of all, new int(3) does not create an array of three ints (as I think you think), but it creates a single int initialized to 3. What you probably meant was new int[3].

    But: new int[3] would need a delete[] to be freed, but auto_ptr uses plain delete, i.e. it's not intended to manage arrays. This because the solution provided by the standard library to manage arrays is std::vector, which you should probably use instead of your homebrew solution, since std::vector has virtually no overhead over a "normal" dynamic array.