c – 使用模板化构造函数时,禁用默认复制构造和赋值构造函数

我正在尝试创建一个可复制的类,它依赖于它的模板参数(bool Copyable),否则只能移动.

当通过模板参数bool Copyable启用时,它可以从类型本身(默认构造函数)到myclass(myclass&&)和myclass(myclass const&)构造.

它也可以使用其他模板参数从myclass构造,我的当前实现通过模板化构造函数和赋值运算符来覆盖它.

此处使用零规则通过继承的可复制助手结构生成默认构造函数和赋值运算符,该结构在bool Copyable为false时禁用复制构造函数和复制赋值运算符.

template<bool>
struct copyable { };

template <>
struct copyable<false>
{
    // Disables copy construct & copy assign
    copyable() = default;
    copyable(copyable const&) = delete;
    copyable(copyable&&) = default;
    copyable& operator=(copyable const&) = delete;
    copyable& operator=(copyable&&) = default;
};

template<typename A, typename B, typename C>
struct storage_t
{
    // Implementation depends on A, B and C
};

template<typename A, typename B, typename C, bool Copyable>
class myclass
    : public copyable<Copyable>
{
    storage_t<A, B, C> _storage;

public:
    // It should generate the default constructors and
    // assignment operatos dependent on its inherited helper struct copyable.

    // Comment this out to disable the error...
    // (Implementation omitted)
    template<typename A, typename B, typename C>
    myclass(myclass<A, B, C, true> const&) { }

    template<typename A, typename B, typename C, bool Copyable>
    myclass(myclass<A, B, C, Copyable>&&) { }

    template<typename A, typename B, typename C>
    myclass& operator= (myclass<A, B, C, true> const&) { return *this; }

    template<typename A, typename B, typename C, bool Copyable>
    myclass& operator= (myclass<A, B, C, Copyable>&&) { return *this; }
    // ... comment end
};

通过在stackoverflow解释早期的答案,如:

> Why does template copy constructor override default copy constructor?
> Copy constructor of template class
> Why can’t I override the default copy constructor and assignment operator with template versions in C++

哪个说:

The compiler will still generates a default copy-constructor for you, instead of instantiating the templated constructor.

我认为编译器仍会生成默认的构造函数,尽管提供了模板化的构造函数.

但是上层示例代码的编译失败并显示错误消息(msvc 2015):

error C2512: ‘myclass’: no appropriate default constructor available:

myclass<int, int, int, true> mc1;

当我超出提供的模板化构造函数和赋值运算符时,将使用默认构造函数,但是为了为myclass分配其他模板参数而丢失功能.

一个简单的用法示例是:

/////
// Testing the copyable class
myclass<int, int, int, true> mc1;

// Copy construct
myclass<int, int, int, true> mc2(mc1);
// Copy assign
mc1 = mc2;

/////
// Testing the move only class
myclass<int, int, int, false> mc3;

// Move construct
myclass<int, int, int, false> mc4(std::move(mc3));
// Move assign
mc3 = std::move(mc4);

// Not working part:
// Copy and move from myclass with other template params
myclass<int, int, float, true> mc5;
// Error here:
mc1 = mc5;

有没有办法通过模板参数禁用复制构造和赋值运算符,还提供模板化构造函数/赋值运算符?

最佳答案 如果提供其他构造函数,则不会生成默认构造函数.

只提供一个默认值:

myclass() = default;

在您的情况下,如果可能,仍然会生成复制构造函数(当您继承可复制的< false>时,情况并非如此).

点赞