重载的构造函数对于移动和复制是非法的

overloaded constructor illegal with move and copy

我有一个正在编写的 class,它将为其其中一个构造函数采用特殊类型,可以是满足我要求的任何类型。我有 运行 这个模板构造函数导致我的复制和移动构造函数成为非法重载的问题!

我的 class 布局如下:

template<typename ... Types>
class myclass{
    public:
        myclass(const myclass &other){/* copy constructor */}
        myclass(myclass &&other){/* move constructor */}

        template<typename Special>
        myclass(Special &&arg){/* stops copy/move implementations */}
}

我怎样才能绕过这个限制?

约束它。

template<typename Special,
         std::enable_if_t<!std::is_same<std::decay_t<Special>, myclass>{}, int> = 0 >
myclass(Special &&arg) { /* ... */ }

根据您的特定用例,您可能还想进一步限制 Special 仅满足您要求的类型。

这个例子展示了不同的情况:

const myclass c1(42);      // special: int
myclass c2(c1);            // copy
myclass c3(c2);            // special: myclass& (non const)
myclass c4(std::move(c3)); // move

Live Demo

您的 copy/move 构造函数仍然是合法的重载,但非 const 左值与您的模板构造函数完全匹配。

您可以:

  • 在模板中使用 SFINAE 禁止 myclass&(如 T.C 的回答)
  • 提供另一个重载(精确匹配):

    myclass(myclass &other) : myclass(static_cast<const myclass &>(other)) {}
    

    Demo