这是一个简化的代码: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)'
如果您修改定义以具有显式定义的移动构造函数,则可以编译,我不知道为什么编译器不生成移动构造函数,但我知道使用 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