Почему конструктор std::unique_ptr при создание переменной - члена класса ругается, что требуется спецификатор типа
Если использовать конструктор для умного указателя, который принимает указатель на переменную, то все нормально работает в основном коде, но в классах, при попытке создать переменную - член типа std::unique_ptr(new type) - ругается компилятор(VS community 2019), что требуется спецификатор типа и принимает создание умного указателя только через std::make_unique. Объясните, пожалуйста, почему так происходит, а не как исправить
#include <iostream>
#include <memory>
class A {
public:
A() { std::cout << "A created\n"; }
~A() { std::cout << "A destroyed\n"; }
};
class B {
std::unique_ptr<A> a(new A);//???
/*std::unique_ptr a = std::make_unique<A>() - works*/
public:
B() { std::cout << "B created\n"; }
~B() { std::cout << "B destroyed\n"; }
};
int main() {
std::unique_ptr<A> a(new A);//Works
return 0;
}
Ответы (2 шт):
В данном случае инициализация поля с использованием синтаксиса copy initialization (то бишь с круглыми скобочками) парсится как объявление метода c именем a. При инициализации полей внутри класса, да и во всех других случаях, следует использовать синтаксис direct list initialization (который также хорош тем, что не допускает понижающих преобразований с потерей данных).
class B {
std::unique_ptr<A> a{new A{}};
public:
B() { std::cout << "B created\n"; }
~B() { std::cout << "B destroyed\n"; }
};
Инициализация членов класса в месте их определения возможна двумями способами:
- через
= - через
{}
struct S {
int a = 1; // ok
int b {2}; // ok
int c (3); // ошибка
};
Вы пытаетесь использовать третий и получаете ошибку.