使用 unique_ptr 遵循 pImpl 习惯用法的类的 unordered_map

问题描述 投票:0回答:1

这是一个简化的代码:https://godbolt.org/z/EnE76xMrP
pImpl 将包含一个互斥体成员,这使得 pImpl 既不可复制也不可移动。但是 Foo 类有 pImpl 的 unique_ptr 作为成员,这使得 Foo 可移动但不可复制。

class Foo final
{
public:
    Foo();
    ~Foo();
    void DoSomething(const int thread_num);
private:
    int data{};
    struct Impl;
    std::unique_ptr<Impl> m_impl;
};

struct Foo::Impl final
{
    mutable std::mutex m_mutex;
};

Foo::Foo()
    : m_impl(std::make_unique<Impl>()) 
{}

Foo::~Foo() {
    std::cout << "Foo dtor \n";
}

为了将键映射到 Foo 值,我使用了 emplace。但看起来即使构建一对也是不可行的。请您澄清一下好吗?因为编译器消息有点麻烦:

no matching function for call to 'std::pair<int, Foo>::pair(int, Foo)'

我尝试使用shared_ptr而不是unique_ptr,它有效,但我的问题是为什么?

c++17 unique-ptr std-pair pimpl-idiom
1个回答
0
投票

如果您修改定义以具有显式定义的移动构造函数,则可以编译,我不知道为什么编译器不生成移动构造函数,但我知道使用 Pimpl 需要声明所有“公开”构造函数和析构函数在标头中,并在 cpp 中实现。

class Foo final
{
public:
    Foo();
    ~Foo();
    Foo(Foo&& other);
    void DoSomething(const int thread_num);
private:
    int data{};
    std::unique_ptr<Impl> m_impl;
};

Foo::Foo(Foo&&) = default; // in the cpp
© www.soinside.com 2019 - 2024. All rights reserved.