包含 unique_ptr 的结构中的默认析构函数在使用 std::map 时会导致编译错误

default destructor in a struct containing a unique_ptr causes compilation errors when using an std::map

考虑以下代码示例,为什么默认析构函数的定义会导致编译错误?

#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;
}

编译器错误:

error: call to implicitly-deleted copy constructor of 'Foo'

从错误消息中我得知正在执行静默复制???

值得一提的是,当使用普通指针而不是 unique_ptr 时,代码编译得很好。但是我不明白为什么默认的析构函数会出问题?

因为如果您自己定义析构函数,那么编译器将不再为您生成 copy-con 和 move-con。您可以将它们指定为默认值并删除(即使由于 unique_ptr 的原因,复制 con 仍将被隐式删除)并且您的代码将再次运行:

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&&)也是如此。