Explicitly choose which template overload should be
Can I choose which template overload function should be used in this case?
struct X { };
struct A { A(X){} };
struct B { B(X){} };
template<class T>
void fun(T, A) { }
template<class T>
void fun(T, B) { }
int main() {
/* explicitly choose overload */ fun(1, X());
}
Mistake:
error: call of overloaded 'fun(int, X)' is ambiguous
/* explicitly choose overload */ fun(1, X());
^
candidate: void fun(T, A) [with T = int]
void fun(T, A) { }
^~~
candidate: void fun(T, B) [with T = int]
void fun(T, B) { }
^~~
For a normal function, it looks like this:
void fun(A){}
void fun(B){}
int main() {
((void(*)(A))(fun))(X());
}
Is it possible?
source to share
If you don't want to explicitly specify the first parameter type, but want to specify the second, you can go along with a lambda designed for the casting purpose (C ++ 14 solution):
struct X { };
struct A { A(X){} };
struct B { B(X){} };
template<class T>
void fun(T, A) { }
template<class T>
void fun(T, B) { }
int main() {
[](auto v, auto x){ static_cast<void(*)(decltype(v), A)>(fun)(v, x); }(1, X());
}
source to share
A low-tech solution to this problem is to add one extra layer of indirection. Add a type function funA
whose sole purpose is to explicitly name the first version fun
:
struct X { };
struct A { A(X){} };
struct B { B(X){} };
template<class T>
void fun(T, A) { }
template<class T>
void fun(T, B) { }
template <class T>
void funA(T t, A a) { fun(t, a); }
int main() {
/* explicitly choose overload */ funA(1, X());
}
However, I wonder why you can't just change the argument to A(X())
. You still have to change the calling code, so what's the problem?
source to share