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.