重载构造函数非法移动和复制

时间:2015-07-31 07:28:51

标签: c++ templates c++14 forwarding-reference

我有一个我正在编写的类,它将为其中一个构造函数采用特殊类型,可以是符合我要求的任何类型。我遇到了这个模板化构造函数导致我的副本并将构造函数移动为非法重载的问题!

我的班级是这样的:

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 */}
}

我如何解决这个限制?

2 个答案:

答案 0 :(得分:5)

限制它。

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

根据您的特定用例,您可能还希望将Special进一步限制为仅符合您要求的类型。

答案 1 :(得分:0)

此示例显示了不同的情况:

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

你的复制/移动构造函数仍然是合法的重载,但非const l-value与你的模板构造函数完全匹配。

你可以:

  • 在模板中使用SFINAE禁止myclass&(如T.C的答案)
  • 提供其他重载(完全匹配):

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

    Demo