Is it possible to provide an automatic conversion for a template class instantiated with const and non-const pointer types?
Specifically, consider the following:
template <typename T>
class A {
public:
operator A<const T>()
{
return A<const T>();
}
};
int main()
{
A<const int> a1;
A<int> a2;
// Works fine; invokes operator A<const T>()
a1 = a2;
A<const int*> a3;
A<int*> a4;
// Fails to compile: no viable overloaded '='
a3 = a4;
return 0;
}
Is it possible to provide an explicit conversion for types with pointer template arguments? What would this look like in the definition of A?
As a bonus/background question, why does the above work for non-pointer template arguments, but not for pointer template arguments?
The source of the confusion is the constness of the pointer vs the constness of the pointee. The setup you have now converts a T
into a const T
. If you substitute int
for T
it works, int
becomes const int
. However, if you substitute int *
you get int * const
, not const int *
. The T
gets a const
, which is a pointer, so the pointer becomes const
, not the object pointed to.
The following code works:
A<int*const> a5;
A<int*> a6;
// compiles
a5 = a6;
You can do some tricky things like
operator A<std::add_pointer_t<std::add_const_t<std::remove_pointer_t<T>>>>()
{
return {};
}
to make a3 = a4;
compile, but you have to be very careful that these conversions actually do what they are supposed to do (the above example incorrectly(?) allows int
to const int *
conversion because remove_pointer
does nothing if the given type is not a pointer, would need to enable_if
+ is_pointer
which gets complicated rather quickly).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With