【问题标题】:default destructor in a struct containing a unique_ptr causes compilation errors when using an std::map使用 std::map 时,包含 unique_ptr 的结构中的默认析构函数会导致编译错误
【发布时间】:2019-11-11 05:55:32
【问题描述】:

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

#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 时,代码编译得很好。但我不明白为什么默认析构函数会有问题?

【问题讨论】:

    标签: c++ dictionary destructor unique-ptr


    【解决方案1】:

    因为如果您自己定义析构函数,那么编译器将不再为您生成 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&amp;&amp;) 也是如此。

    【讨论】:

    • 当然!!!啊啊啊!!!现在我记得在 Effective Modern C++ 中读过它。实际上定义析构函数会阻止创建移动构造函数。复制构造函数是从 C++98 中生成的!谢谢!
    猜你喜欢
    • 2012-07-26
    • 2014-11-24
    • 1970-01-01
    • 2013-04-18
    • 2021-09-25
    • 1970-01-01
    • 2018-01-01
    • 2021-09-29
    • 1970-01-01
    相关资源
    最近更新 更多