I experience overload behavior that seems very unexpected. The following code is rejected with an ambiguity error for both gcc and clang:
template <typename T>
struct A
{
typedef T key_type;
};
template <typename T>
void foo(A<T> rng, T val);
template <typename T, typename U = T>
void foo(T, typename U::key_type);
int main()
{
A<int> i;
foo(i, 0);
}
Error:
test.cpp:16:5: error: call to 'foo' is ambiguous
foo(i, 0);
^~~
test.cpp:8:6: note: candidate function [with T = int]
void foo(A<T> rng, T val);
^
test.cpp:11:6: note: candidate function [with T = A<int>, U = A<int>]
void foo(T, typename U::key_type);
^
I would expect both to be exact matches, but the first overload is to win in partial order, since the first parameter is A<T>more specialized than T.
Which makes me think that if I change the second signature to:
template <typename T, typename U = T>
void foo(T, typename T::key_type);
and gcc and clang now take the code and select the first overload, as I expected initially.
, : , , , (U) (T).
, , , , - .
- :
, , , , gcc 4.8.0 clang.