Замена аргумента функции по умолчанию при повторном объявлении

Почему следующий код правильно сформирован:

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

int main(){  }

ДЕМО

Но следующее

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

int main(){  }

ДЕМО

плохо сформирован. Я попытался найти в N4296::8.3.6 [dcl.fct.default] и нашел следующий пример:

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
}

Но кланг так не кажется.

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

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

int main(){  }

ДЕМО

Так это проблема реализации? Формально весь этот пример должен быть приемлем, не так ли?


person Community    schedule 07.01.2015    source источник
comment
Аргумент по умолчанию должен быть объявлен в функции справа налево, я думаю, в соответствии со стандартом...   -  person Ankur    schedule 07.01.2015


Ответы (1)


[dcl.fct.default]

  1. [...] аргументы по умолчанию могут быть добавлены в более поздние объявления функции в той же области.
void foo(int i, int j = 56);
void foo(int i = 42, int j);

Это нормально, потому что второе объявление добавляет аргумент по умолчанию к первому параметру, у которого раньше его не было.

[...] В данном объявлении функции каждый параметр, следующий за параметром с аргументом по умолчанию, должен иметь аргумент по умолчанию, указанный в этом или предыдущем объявлении[...]

Второй параметр во втором объявлении уже имеет аргумент по умолчанию, попытка указать другой будет ошибкой.

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

Это ошибка, потому что первое объявление дает аргумент по умолчанию для первого параметра, но не для второго, и в отличие от первого примера нет предыдущих объявлений.

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

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

Это неверно по тем же причинам, что и выше, j не имеет аргумента по умолчанию в исходном объявлении, следующая строка в вашем примере не имеет значения.

person user657267    schedule 07.01.2015
comment
Вы были очень ясны. Спасибо за этот ответ! Ключевым моментом было то, что после объявления аргумента по умолчанию все остальные последующие аргументы также должны иметь значения по умолчанию. - person ; 08.01.2015