Я написал экзамен по программированию на C ++. Был один вопрос, где я и мой профессор не согласились. Вопрос был в том, работает ли следующая функция:
#include <iostream>
using namespace std;
void f(int=4, long=10, double=3.14);
int main( int argc , char ** argv )
{
f( , ,8);
return EXIT_SUCCESS;
}
void f(int i, long l, double d) {
cout << i << " " << " " << l << " " << d;
}
Я сказал, что это не будет работать, но мой профессор сказал, что это точно будет работать из-за параметра по умолчанию в объявлении функции. Я попробовал это с MSVC, и это не сработало. Это зависит от компилятора? Как я могу убедить своего профессора, что он не работает ни в одном компиляторе, поднять мою оценку на экзамене?
Начнем с того, что вы правы, профессор не прав. И тот факт, что он утверждает, что это должно работать (когда банально показать, что это не так) означает, что он, вероятно, не должен учить C ++. Но как его показать?
Просто попробуйте скомпилировать его как минимум двумя разными компиляторами. Если оба не скомпилируют его, то очень вероятно, что это неверный код. Это самый быстрый способ.
Если это не помогло, процитируйте стандарт C ++. Вот синтаксис для выражения вызова, как описано в [expr.post] p1 и после нетерминальных ссылок:
postfix-expression:
...
postfix-expression ( expression-list[opt] )
expression-list:
initializer-list
initializer-list: ([dcl.init]p1)
initializer-clause ...[opt]
initializer-list , initializer-clause ...[opt]
initializer-clause:
assignment-expression
braced-init-list
braced-init-list:
{ initializer-list ,[opt] }
{ }
Я не собираюсь перечислять присваивание-выражение, но учтите, что выражение никогда не может быть ничем, должен быть хотя бы один токен. Это означает, что предложение инициализатора никогда не может быть ничем, и поэтому всегда должно быть что-то между запятыми в аргументах функции.
Из Стандарта (выделите мое, обратите особое внимание на слово задний):
8.3.6 Аргументы по умолчанию [dcl.fct.default]
Если предложение-инициализатор указано в объявлении параметра, это предложение-инициализатор используется в качестве аргумента по умолчанию. Аргументы по умолчанию будут использоваться в вызовах, где конечные аргументы отсутствуют.
- [Пример: объявление
void point(int = 3, int = 4);
объявляет функцию, которая может быть вызвана с нулем, одним или двумя аргументами типа int. Это можно вызвать любым из этих способов:
point(1,2); point(1); point();
Последние два вызова эквивалентны
point(1,4)
а такжеpoint(3,4)
соответственно.— конец примера]
Наслаждайтесь возвращением своих очков. 😉
Это даже не действительный C ++ синтаксис.
Это, вероятно, потому, что это работает только для опущенных конечных параметров, как сказано MSDN. Попробуйте вызвать функцию следующим образом:
f(); // should use all default values for arguments
f(3); // should use 3 for the first, default for the last two
f(2, 5); // uses 2 for first, 5 for second, default for last
f(5, 6, 3.4); // does not use any default values