4

Why the following code is well-formed:

void foo(int i, int j = 56);
void foo(int i = 42, int j);

int main(){  }

DEMO

But the following

void foo(int i = 42, int j);
void foo(int i, int j = 56);

int main(){  }

DEMO

is ill-formed. I tried to look up in the N4296::8.3.6 [dcl.fct.default] and what I found was the following example:

class C 
{
    void f(int i = 3);
    void g(int i, int j = 99);
};
void C::f(int i = 3) { } //error
void C::g(int i = 88, int j) { // C::g can be called with no argument
}

But clang doesn't seem that way.

struct A
{
    void foo(int i = 42, int j);
};

void A::foo(int i, int j = 56){ }; //error

int main(){  }

DEMO

So, is it an implementation issue? Formally, all this example should be acceptable, should they?

  • Default argument should be declared in function from right to left i guess according to standard... – Ankur Jan 07 '15 at 06:34

1 Answers1

1

[dcl.fct.default]

  1. [...]default arguments can be added in later declarations of a function in the same scope.
void foo(int i, int j = 56);
void foo(int i = 42, int j);

This is fine because the second declaration is adding a default argument to the first parameter, which previously didn't have one.

[...]In a given function declaration, each parameter subsequent to a parameter with a default argument shall have a default argument supplied in this or a previous declaration[...]

The second parameter in the second declaration already has a default argument, trying to provide another one would be an error.

void foo(int i = 42, int j); // error
void foo(int i, int j = 56);

This is an error because the first declaration gives a default argument for the first parameter, but not the second, and there are no previous declarations unlike the first example.

struct A
{
    void foo(int i = 42, int j); // the error should be here
};

void A::foo(int i, int j = 56){ }; // not here

This is incorrect for exactly the same reasons as above, j has no default argument in the initial declaration, the next line in your example is irrelevant.

user657267
  • 20,568
  • 5
  • 58
  • 77
  • You were very clear. Thank you for that answer! The key thing was once you declare a default argument all of the rest of subsequet arguments should have the defaults too. –  Jan 08 '15 at 04:24