Как инициализировать std::unique_ptr в конструкторе?

А.хпп:

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()));
}

Выдается ошибка, которую я получаю:

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

Кто-нибудь знает, почему это происходит? Я пробовал много разных способов заставить это работать, но безрезультатно.


person Community    schedule 08.10.2013    source источник


Ответы (2)


Вам нужно инициализировать его с помощью списка member-initializer:

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

В вашем примере была попытка вызвать operator () на unique_ptr, что невозможно.

Обновление: кстати, C++14 имеет std::make_unique:

A::A(std::string filename) :
    file(std::make_unique<std::ifstream>(filename));
{ }
person 0x499602D2    schedule 08.10.2013
comment
В качестве альтернативы вызовите функцию reset() для file, чтобы назначить unique_ptr, если вам нужно заранее выполнить некоторую проверку в конструкторе. - person gigaplex; 08.10.2013
comment
Вам не обязательно использовать список членов-инициализаторов. Хотя это предпочтительнее. - person JohnJohn; 29.01.2015
comment
@JohnJohn, если вы используете Pimpl, вам следует использовать список инициализаторов членов, поскольку ваш std::unique_ptr является константой. - person csguth; 27.09.2016
comment
Относительно использования file(new ...) против file(std::make_unique...): есть ли причина предпочесть одно другому? - person Dirk Herrmann; 25.09.2020

Вы можете сделать это следующим образом:

A:A(std::string filename)
    : file(new std::ifstream(filename.c_str())
{
}
person Jonathan Potter    schedule 08.10.2013