Как создать объект unique_ptr со структурой внутри класса?
у меня есть такой класс:
template <typename T>
class Store {
private:
struct pointNode {
T data;
std::unique_ptr<pointNode> next;
pointNode(T n_data,std::unique_ptr<pointNode> ptr) : data(std::move(n_data)), next(std::move(ptr)) {}
};
std::unique_ptr<pointNode> head;
public:
Store() : head(std::make_unique<pointNode>()) {}
Store(const T& data);
Store(const T& data, std::unique_ptr<pointNode> ptr);
void push(const T& data);
};
Я хочу создать временный объект pointNode в функции для хранения :
template <typename T>
void Stack<T>::push(const T& data) {
auto temp = std::make_unique<pointNode>(data,nullptr);
}
Но вылезает ошибка компиляции ,что нет подходящего конструктора по умолчанию. Не могу понять какой еще конструктор нужно сделать, это строчка всегда дает ошибку
auto temp = std::make_unique<pointNode>(data,nullptr);
Был бы рад помощи ,спасибо.
Ответы (2 шт):
Компилятор наврал. Ошибка в этой строке.
Store() : head(std::make_unique<pointNode>())
Можно добавить немного магии и скомпилит:
Store() : head(std::make_unique<pointNode>(T{}, std::unique_ptr<pointNode>{}))
Как уже указано в смежном ответе, ошибка должна ссылаться на конструкцию std::make_unique<pointNode>() по причине отсутствия у pointNode конструктора по умолчанию. И здесь есть несколько путей решения:
- Использовать имеющийся конструктор с двумя аргументами (уже показали)
- Добавить конструктор по умолчанию (самое простое сделать это через
= default) - Удалить имеющийся конструктор (сделав тем самым класс
pointNodeаггрегатным классом). Необходимыеstd::moveможно будет делать прямо по месту.
В третьем случае, если понадобится выполнять создание unique_ptr для инициализации отдельных членов как, например, в std::make_unique<pointNode>(data, nullptr);, то надо либо переходить на C++20 (там make_unique работает для аггрегатов), либо для C++14/17 использовать следующую запись std::unique_ptr<pointNode>(new pointNode{data, nullptr});