I have the following class:
template <typename T1>
class Foo {
public:
Foo(T1* obj) : obj(obj) {}
template <typename T2>
Foo(const Foo<T2>& other) : obj(other.obj) {}
template <typename T2>
explicit operator Foo<T2>() {
return Foo<T2>(static_cast<T2*>(obj));
}
T1* obj;
};
The intention of the second constructor is that an implicit conversion from Foo<X> to Foo<Y> is allowed iff an implicit conversion from X* to Y* is allowed.
The conversion operator is there to allow an explicit conversion from Foo<X> to Foo<Y> using an explicit conversion from X* to Y*.
But I noticed that the conversion operator never gets used. The compiler always uses the second constructor even when I do an explicit cast. This causes an error if an implicit conversion of the underlying types is not possible.
The following code can be used to test the class above.
class X {};
class Y : public X {};
int main() {
Y obj;
Foo<Y> y(&obj);
Foo<X> x = y; // implicit cast works as expected.
// y = x; // implicit conversion fails (as expected).
// y = static_cast<Foo<Y>>(x); // conversion fails because constructor is
// called instead of conversion operator.
}
Is there a way to cause the compiler to use the conversion operator for explicit conversions?
explicit. - user0042Foo<Y>to pass to a template function; you accidentally convert aFoo<X>in an invalid way). Instead, I'd have a function that clearly is a static foo cast, so you can see the points of danger, and it only happens when you mean it to. - Yakk - Adam Nevraumont