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?
Maybe it's because you declared&defined the overloaded function "foo(double)" after the template, so it doesn't know anything about its existence . ->structured programming. I'd suggest:
Here is what the standard says about this. First, in 8.3.6 [dcl.fct.default] paragraph 5:
Further in 14.7.1 [temp.inst] paragraph 12:
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.
This program suggests that the set of functions considered follows normal overload resolution rules:
When compiled with
g++-4.6
, this program outputs:In other words,
foo
is resolved via ADL whenbar
is instantiated.The behavior for the code from the OP seems to be that ADL does not apply to primitives such as
int
anddouble
, so the only overloads considered are those declared beforefoo
's call. The odd MSVC behavior seems to be non-standard.