I'm writing a wrapper template class which can wrap an arbitrary type and imbue it with some additional semantics, but I can't figure out how to get overload resolution to work properly. The issue arises when a conversion that would ordinarily be resolved by comparing ranks of competing conversion sequences, cannot be deduced by the compiler because the type in question is a template argument, rather than a function argument. For instance,
#include <type_traits>
template <typename T> class Wrapper {
T val;
public:
Wrapper() = default;
template <typename U> Wrapper(Wrapper<U> x) : val(x.val) {}
};
void foo(Wrapper<const char *>) {}
void foo(Wrapper<bool>) {}
int main() {
Wrapper<char *> cp;
foo(cp);
}
Here, the call to foo() is ambiguous. The desired behavior would be for the compiler to select void foo(Wrapper<const char *>), as it would if cp were instead a char * and foo were instead void foo(const char *). Is this possible?
EDIT: Thanks to everyone for the quick responses, but perhaps I should have been more clear. What I have given above is just an example. What I require is a general solution to the following question: given arbitrary types T, U, and V, suppose that C++'s built in overload resolution would prefer the conversion T -> U over T -> V. How can I then also ensure that C++ would prefer Wrapper<T> -> Wrapper<U> over Wrapper<T> -> Wrapper<V>?
I made this clarification because it seemed that the answers were specifically addressing certain aspects of overload resolution, like cv-qualifiedness, whereas I really need a general solution.