У меня есть класс, который я пишу, который будет принимать специальный тип для одного из своих конструкторов, который может быть любого типа, который соответствует моим требованиям. Я столкнулся с проблемой, что этот шаблонный конструктор приводит к тому, что мои конструкторы копирования и перемещения становятся недопустимыми перегрузками!
Мой класс выложен так:
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
Ваши конструкторы копирования / перемещения все еще допустимы, но неконстантное l-значение точно соответствует вашему конструктору шаблона.
Ты можешь:
myclass&
в шаблоне (как в ответе Т.С.)обеспечить другую перегрузку (с точным соответствием):
myclass(myclass &other) : myclass(static_cast<const myclass &>(other)) {}