Meditation, The Art of Exploitation

Thinking? At last I have discovered it--thought; this alone is inseparable from me. I am, I exist--that is certain. But for how long? For as long as I am thinking. For it could be, that were I totally to cease from thinking, I should totally cease to exist....I am, then, in the strict sense only a thing that thinks.

Monday, May 08, 2006

Default arguments do not participate in overload resolution

Consider the following code:

// (1)
template
void f(T const& x) {}

// (2)
template
void f(T const& x, typename T::some_type* = 0) {}

struct X { typedef int some_type; } x;

int main()
{
f(x);//Comeau choose #2. Does it conform to the Standard?

}

First, the compiler builds a viable function set. This is where SFINAE takes place and a function is either added or excluded from the set. According to 13.3.2/2

A candidate function having more than m parameters is viable only if the (m+1)-st parameter has a default argument (8.3.6).121) For the purposes of overload resolution, the parameter list is truncated on the right, so that there are exactly m parameters.

So, the viable set in this case contains functions with the default argument truncated.

Second, the compiler does partial template ordering and the actual overload resolution. Since the default argument for function 2 has been truncated, the viable function set here contains 2 identical functions which results in the ambiguity.