Как создать объект 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 конструктора по умолчанию. И здесь есть несколько путей решения:

  1. Использовать имеющийся конструктор с двумя аргументами (уже показали)
  2. Добавить конструктор по умолчанию (самое простое сделать это через = default)
  3. Удалить имеющийся конструктор (сделав тем самым класс 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});

→ Ссылка