Which set of functions is taken into account when resolving overloaded functions affecting the default parameter values?

advertisements

Consider the function bar below, whose parameter has a default value initialized from an invocation of an overloaded foo:

#include <iostream>

int foo(int x)
{
  std::cout << "foo(int)" << std::endl;
  return 0;
}

template<typename T>
void bar(T a, int x = foo(T(0))) {}

double foo(double x)
{
  std::cout << "foo(double)" << std::endl;
  return 0;
}

int main()
{
  bar<int>(1);
  bar<double>(1);
  return 0;
}

I expect this program to output

foo(int)
foo(double)

corresponding to foo's two overloads which are visible at bar's instantiation.

Instead, when compiled with g++-4.6, the output is

$ g++-4.6 -std=c++0x test.cpp; ./a.out
foo(int)
foo(int)

Is the set of overloads considered when implementing a default parameter value different from normal overload resolution? Is this case described in the ISO C++ standard?


Here is what the standard says about this. First, in 8.3.6 [dcl.fct.default] paragraph 5:

... The names in the default argument are bound, and the semantic constraints are checked, at the point where the default argument appears. Name lookup and checking of semantic constraints for default arguments in function templates and in member functions of class templates are performed as described in 14.7.1. ...

Further in 14.7.1 [temp.inst] paragraph 12:

If a function template f is called in a way that requires a default argument to be used, the dependent names are looked up, the semantics constraints are checked, and the instantiation of any template used in the default argument is done as if the default argument had been an initializer used in a function template specialization with the same scope, the same template parameters and the same access as that of the function template f used at that point. This analysis is called default argument instantiation. The instantiated default argument is then used as the argument of f.

I'm not quite sure what this exactly says. I can see both interpretations in this text. In case it matters, I think EDG agrees with gcc and clang.