3

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

我的班级是这样安排的:

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

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

4

2 回答 2

5

约束它。

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

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

于 2015-07-31T07:38:22.603 回答
0

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

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

现场演示

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

您可以:

  • 使用 SFINAE 在模板中禁止myclass&(如 TC 的回答)
  • 提供另一个重载(完全匹配):

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

    演示

于 2015-07-31T07:42:53.567 回答