You can force ADL:
struct foo {
friend foo f(foo *) { return {}; }
};
int main()
{
auto x = f((foo *) 0);
return 0;
}
Compiles with g++ 4.9.0 and clang++ 3.4. Of course, might not be practical.
ADDENDUM: Thanks to Richard Hodges, here is another possible workaround, but it might be a g++ 4.9.0 bug. There are differences between clang++ and g++. I'll try to look into what the standard says, if I have time. If the OP wants to post this as a new question asking about which compiler is wrong, please do.
struct foo {
friend foo f1() { return {}; }
friend foo f2(foo *) { return {}; }
template<typename T = void>
friend foo f3() { return {}; }
};
int main()
{
auto x1 = f1(); // Error, f1() not visible.
auto x2 = f2((foo *) 0); // Force ADL.
auto x3 = f3<void>(); // Use template, okay with g++, fails with clang++.
auto x4 = f3(); // Use template with default param, okay with g++, fails with clang++.
return 0;
}