Reputation: 5518
I have a class that I'm writing that will take a special type for one of its constructors that could be any type that fits my requirements. I have run into the issue that this templated constructor causes my copy and move constructors to be illegal overloads!
My class is layed out like this:
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 */}
}
How can I get around this limitation?
Upvotes: 3
Views: 95
Reputation: 137425
Constrain it.
template<typename Special,
std::enable_if_t<!std::is_same<std::decay_t<Special>, myclass>{}, int> = 0 >
myclass(Special &&arg) { /* ... */ }
Depending on your particular use case, you may also want to constrain Special
further to only types that fit your requirements.
Upvotes: 5
Reputation: 217810
This example shows the different cases:
const myclass c1(42); // special: int
myclass c2(c1); // copy
myclass c3(c2); // special: myclass& (non const)
myclass c4(std::move(c3)); // move
your copy/move constructors are still legal overloads, but non const l-value has an exact match with your template constructor.
You may:
myclass&
in the template (as in T.C's answer)provide an other overload (with exact match):
myclass(myclass &other) : myclass(static_cast<const myclass &>(other)) {}
Upvotes: 0