46

A.hpp:

class A {
  private:
   std::unique_ptr<std::ifstream> file;
  public:
   A(std::string filename);
};

A.cpp:

A::A(std::string filename) {
  this->file(new std::ifstream(filename.c_str()));
}

The error that I get is thrown:

A.cpp:7:43: error: no match for call to ‘(std::unique_ptr<std::basic_ifstream<char> >) (std::ifstream*)’

Does anyone have any insight as to why this is occurring? I've tried many different ways to get this to work but to no avail.

  • [This](https://stackoverflow.com/questions/8114276/how-do-i-pass-a-unique-ptr-argument-to-a-constructor-or-a-function) is related – mrpandey Dec 27 '22 at 10:19

2 Answers2

56

You need to initialize it through the member-initializer list:

A::A(std::string filename) :
    file(new std::ifstream(filename));
{ }

Your example was an attempt to call operator () on a unique_ptr which is not possible.

Update: BTW, C++14 has std::make_unique:

A::A(std::string filename) :
    file(std::make_unique<std::ifstream>(filename));
{ }
David G
  • 94,763
  • 41
  • 167
  • 253
  • 5
    Alternatively call the `reset()` function on `file` to assign the `unique_ptr` if you need to do some checking in the constructor beforehand. – gigaplex Oct 08 '13 at 00:54
  • You don't necessarily have to use member-initializer list. It is more preferable though. – JohnJohn Jan 29 '15 at 10:30
  • 1
    @JohnJohn, if you're using Pimpl, you should use member-initializer list, since your std::unique_ptr is const. – csguth Sep 27 '16 at 17:48
  • 1
    Regarding the use of `file(new ...)` vs. `file(std::make_unique...)`: Is there any reason to prefer one over the other? – Dirk Herrmann Sep 25 '20 at 18:33
6

You can do it like this:

A:A(std::string filename)
    : file(new std::ifstream(filename.c_str())
{
}
Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79