перегруженный конструктор недопустим при перемещении и копировании

У меня есть класс, который я пишу, который будет принимать специальный тип для одного из своих конструкторов, который может быть любого типа, который соответствует моим требованиям. Я столкнулся с проблемой, что этот шаблонный конструктор приводит к тому, что мои конструкторы копирования и перемещения становятся недопустимыми перегрузками!

Мой класс выложен так:

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

Как я могу обойти это ограничение?

3

Решение

Ограничить это.

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

В зависимости от вашего конкретного случая использования, вы также можете ограничить Special дальше только типы, которые соответствуют вашим требованиям.

5

Другие решения

Этот пример показывает разные случаи:

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

Ваши конструкторы копирования / перемещения все еще допустимы, но неконстантное l-значение точно соответствует вашему конструктору шаблона.

Ты можешь:

  • использовать SFINAE, чтобы запретить myclass& в шаблоне (как в ответе Т.С.)
  • обеспечить другую перегрузку (с точным соответствием):

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

    демонстрация

0

По вопросам рекламы [email protected]