деструктор по умолчанию в структуре, содержащей unique_ptr, вызывает ошибки компиляции при использовании std :: map - PullRequest
1 голос
/ 30 июня 2019

Учитывая следующий пример кода, почему определение деструктора по умолчанию вызывает ошибку компиляции?

#include <iostream>
#include <memory>
#include <map>

struct Foo
{
    char c;
    std::unique_ptr<int> ptr;

    Foo(char c_, int n_) : c(c_), ptr(std::make_unique<int>(n_))
    {;}

    //~Foo() noexcept = default; // problem here, why?
};


int main()
{
    std::map<int, Foo> mp;

    mp.emplace(0, Foo{'a',40});
    mp.emplace(1, Foo{'b',23});

    for (auto &&i : mp)
        std::cout<< i.first << " : {" << i.second.c << "," << *(i.second.ptr) << "}" <<std::endl;
}

Ошибка компилятора:

ошибка: вызов неявно-удаленногоконструктор копирования 'Foo'

Из сообщения об ошибке я получаю, что происходит тихое копирование ???

Стоит отметить, что код прекрасно компилируется при использовании обычного указателявместо unique_ptr.Но я не понимаю, почему деструктор по умолчанию будет проблемой?

1 Ответ

2 голосов
/ 30 июня 2019

Потому что, если вы сами определите деструктор, то компилятор больше не будет генерировать для вас copy-con и move-con. Вы можете указать их по умолчанию и удалить (даже если копия con все равно будет неявно удалена из-за причины unique_ptr), и ваш код снова будет работать:

struct Foo
{
    char c;
    std::unique_ptr<int> ptr;

    Foo(char c_, int n_) : c(c_), ptr(std::make_unique<int>(n_))
    {;}

    ~Foo() noexcept = default;
    Foo(Foo&&) = default;
};

Это также относится к operator=(Foo&&).

...