Reputation: 7946
I've learned that the C++11 standard doesn't allow friend functions to have default arguments unless the friend declaration is a definition. So this isn't allowed:
class bar
{
friend int foo(int seed = 0);
};
inline int foo(int seed) { return seed; }
but this is:
class bar
{
friend int foo(int seed = 0)
{
return seed;
}
};
(Example courtesy http://clang-developers.42468.n3.nabble.com/Clang-compile-error-td4033809.html)
What is the rational behind this decision? Friend functions with default arguments are useful, e.g. if the function is too complex to declare in place, why are they now disallowed?
Upvotes: 3
Views: 538
Reputation: 4591
In looking at DR 136, it looks like there are issues when a friend declaration combines with namespace-level declarations with default arguments that makes the semantics hard to reason about (and perhaps difficult to issue quality diagnostics against), especially in the context of templates. The proposed DR resolution given on that page is to only allow default arguments in them when the declaration is the only one in the program. Since a function definition is also a declaration, that would mean the only useful way to specify default arguments in a friend declaration is to make it a definition. I would guess the C++11 standard simply chose to make this practical usage requirement explicit.
(Technically, if by "program" they mean "translation unit", one could construct a complete program where the function were defined in a completely different translation unit, but since this function's definition would not have the class definition visible, the benefits of the friendship grant would be largely useless.)
The workaround for this hiccup seems pretty straightforward. Declare the friend without using default arguments, and then declare it again at namespace scope with whatever default arguments are desired.
Upvotes: 5