Reputation: 22744
I got in a situation where I have a number of pair of classes, which I'll call Legacy
and Modern
, which have converting constructors from the same types.
struct Legacy { Legacy(int); };
struct Modern { Modern(int); };
Potentially, even templated constructors:
struct Legacy { template <typename T> Legacy(T); };
struct Modern { template <typename T> Modern(T); };
Similarly, there's a number of functions overloaded on those types:
void f(Legacy) { ... }
void f(Modern) { ... }
Is there a way to modify Legacy
and Modern
's constructors in a way that Modern
's is always preferred for implicit conversions?
f(42); // should call f(Modern(42))
[over.ics.user] doesn't seem to allow for any ranking in implicit conversions involving user-defined conversions (in other words the call is ambiguous, and that's it), but maybe I'm overlooking something.
Upvotes: 4
Views: 70
Reputation: 96241
The easiest way to do this is to make Legacy
's constructor explicit. This should have the same end-effect as a ranking because even if you had "ranked" implicit constructors the only way to call Legacy
's is to explicitly call it.
That said, converting constructors can be a source of confusion and bugs so you might consider making BOTH of them explicit.
Upvotes: 2