Consider the following code:
#include <iostream> template <class W, class T> void foo(W& a, T& t) { std::cout << "generic" << std::endl; } template <template <bool> class W, class T> void foo(W<true>& a, const T& t) { foo(a, const_cast<T&>(t)); } template <class W> void foo(W& a, int& t) { std::cout << "int" << std::endl; } template <bool> struct what; template<> struct what<true> { }; int main() { const int ci = 10; what<true> wt; foo(wt, ci); return 0; }
Output signal ( ideone link ):
int
This makes sense to me: foo(what<true>&, const int&) corresponds to a const_cast overload, which then calls foo(what<true>&, int&) , which corresponds to an int overload.
But if I changed the const_cast function to the following:
template <template <bool> class W, class T> void foo(W<true>& a, const T& t) { ::foo(a, const_cast<T&>(t)); }
Now output ( ideone link ):
generic
That doesn't make sense to me. Why const_cast changing this const_cast overload of foo to a call ::foo cause the generic version to receive the call instead of the int version?
My understanding :: is that you just need to eliminate which function to call if you have a method or function in the global namespace. The overload of const_cast is still the same, which then should call ::foo(what<true>&, int&) , which should match the int specialization - isn't it?
Also, if I change the order and put the const_cast overload using ::foo after the int specialization, then the int ( ideone link ) specialization will be called. Why is the order of definition defined here?
c ++ templates overload-resolution template-specialization
Claudiu
source share