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

StackOverflow https://stackoverflow.com/questions/10020957

  •  29-05-2021
  •  | 
  •  

Question

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!

Was it helpful?

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.

OTHER TIPS

Your trouble isn't with auto_ptr, but with constructors in C++. You need to initialize class members in the constructor initializer list:

Toy() : line(new int(3)) { }

Note that this creates a single dynamic int with value 3.

You are not calling a constructor. Instead, you try to call a non-existent function-call operator. These would call the constructor:

Toy() : line(new int(3)) {

or (not exactly what you want)

Toy() {
    auto_ptr<int> line(new int(3));

or (as above, not what you want)

Toy() {
    auto_ptr<int>(new int(3));

That's not where you construct member variables. You want to use an initializer list.

Toy() 
    : line(new int(3))
{ }

Members are constructed just before your classes constructor code runs. You can assign them in the constructor code though. They are constructed in the order they appear in the class definition, not in the order they appear in this list. Most compilers will warn you if this list is out of order, just because that avoids confusion. You can also construct parent objects in the same way, by using the parent class' type (since it has no name)

class Toy : public Thing {
   Toy() : Thing("APPLE") {}
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top