Suppose there is a template class template <class T> myclass;
.
Is there an idiomatic way to allow conversion of objects of non-const T
to objects of const T
?
Basically, I want the following conversion to happen implicitly:
void f(myclass<const int> x);
myclass<int> a;
f(a); // should compile
IMPORTANT EDIT:
It appears that the answer is very trivial (and the question is quite silly) but there is something very conceptual involved (at least for me).
I was under the impression that I need to conditionally enable a conversion operator because a conversion operator from myclass<const T>
to myclass<const T>
doesn't make any sense, i.e. I need to declare the conversion operator if and only if T
was const
qualified. I was expecting the compiler to complain about a redundant conversion operator.
Now given that the compiler is happy with the identity conversion operator which converts type X
to X
, what's the difference between the assignment operator or the copy constructor and the identity conversion operator?
MSVC throws a warning for an identity conversion operator. This isn't great.
You can do this using a conversion operator that returns a myclass
with the type const qualified. That looks like
template<typename T>
struct myclass
{
T foo;
operator myclass<const T>() { return myclass<const T>{foo}; }
};
and then in
int main()
{
myclass<int> a{42};
f(a); // should compile
}
the compiler will implicitly call it for you.
If you already have a myclass<const int>
and you pass it to f
you don't have to worry about any ambiguity since the copy constructor is an exact match so that is what is called. However, if you do want to disable the conversion operator when T
is already const
then you can use
template<typename U = T, std::enable_if_t<!std::is_const_v<U>, bool> = true>
operator myclass<const U>() { return myclass<const U>{foo}; }