Unexpected overload resolution with default function template parameter

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.

+5
1

, . , , .

, , , , http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#697.

, ( ). , , , .

, ( , , , ). , (, U, "" .

Clang GCC . , T U::key_type, U, : ", . " , ! ". ". , T T::key_type. , WhatEver::key_type T, T . , , , , .

, , .

, , , . [. , . - ]

, T , /. U undeduced, " ", .

+2

All Articles