首页 > 解决方案 > 构建具有工厂功能的不可移动底座

问题描述

我有一个不可移动的基类,我想使用工厂函数构造它。如果它只是一个成员,而不是一个基地,一切都很好:

#include <utility>
#include <mutex>

struct NonMoveable
{
    std::mutex m;
};

struct WithMember
{
    NonMoveable v;
    template <typename Factory>
    WithMember(Factory f) : v{f()} { }
};

WithMember with_member()
{
    return WithMember{[] { return NonMoveable{}; }};
}

但如果NonMoveable是基数,编​​译器会抱怨隐式删除的复制构造函数:

#include <utility>
#include <mutex>

struct NonMoveable
{
    std::mutex m;
};

struct WithBase
    : NonMoveable
{
    template <typename Factory>
    WithBase(Factory f) : NonMoveable(f()) { }
};

WithBase with_base()
{
    return WithBase{[] { return NonMoveable{}; }};
}

这是错误:

<source>:20:27: error: call to implicitly-deleted copy constructor of 'NonMoveable'    
    WithBase(Factory f) : NonMoveable(f()) { }    
                          ^           ~~~

<source>:30:12: note: in instantiation of function template specialization 'WithBase::WithBase<(lambda at <source>:30:21)>' requested here    
    return WithBase{[] { return NonMoveable{}; }};    
           ^

<source>:6:16: note: copy constructor of 'NonMoveable' is implicitly deleted because field 'm' has a deleted copy constructor    
    std::mutex m;    
               ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/std_mutex.h:94:5: note: 'mutex' has been explicitly marked deleted here    
    mutex(const mutex&) = delete;    
    ^

1 error generated.    
Compiler returned: 1

Godbolt 链接:https ://godbolt.org/z/2PnFsa

我有一种感觉,这是标准中的一些模糊规则。是什么阻止了它的工作,这是保持这种状态的充分理由吗?

标签: c++language-lawyerc++17

解决方案


推荐阅读