Параметр по умолчанию C/С++, заданный как предыдущий аргумент
Мне не удалось найти четкого ответа на это, хотя это может быть связано с тем, что я не использовал правильные условия поиска, поэтому, пожалуйста, перенаправьте меня, если это так. Можно ли использовать предыдущие аргументы в списке параметров функций как значение по умолчанию для более поздних аргументов в списке параметров? Например,
void f( int a, int b = a, int c = b );
Если это возможно, существуют ли какие-либо правила использования? Любая разница между C и С++?
Ответы
Ответ 1
Ответ - нет, вы не можете. Вы можете получить нужное поведение с помощью перегрузки:
void f(int a, int b, int c);
inline void f(int a, int b) { f(a,b,b); }
inline void f(int a) { f(a,a,a); }
Как и в последнем вопросе, C вообще не разрешает параметры по умолчанию.
Ответ 2
Нет, это не законный С++. Это указано в разделе 8.3.6/9 стандарта С++:
По умолчанию аргументы оцениваются время, вызываемое функцией. порядок оценки аргументов функции не указано. Вследствие этого, параметры функции не должны быть используется в выражениях аргументов по умолчанию, даже если они не оценены.
и
int f (int a, int b = a);//ошибка: параметр a используется как аргумент по умолчанию
И C89 по крайней мере не поддерживает значения параметров по умолчанию.
Ответ 3
В качестве потенциального обходного пути вы можете сделать:
const int defaultValue = -999; // or something similar
void f( int a, int b = defaultValue, int c = defaultValue )
{
if (b == defaultValue) { b = a; }
if (c == defaultValue) { c = b; }
//...
}
Ответ 4
Это невозможно
Ответ 5
Нет, вы не можете этого сделать.
Вы обязательно получите сообщение об ошибке "Локальная переменная может не отображаться в этом контексте".
Ответ 6
Я не думаю, что вы можете это сделать, поскольку это незаконный синтаксис. Но, однако, обратитесь к стандарту C99 в формате pdf (n1136.pdf).
Однако вы можете обойти это, используя static
, как при объявлении переменных static и использовании их в функции f
static int global_a;
/* In some other spot where you are calling f(), do this beforehand */
/* global_a = 4; f(); */
void f(void){
int a = global_a;
b = c = a;
/* ..... */
}
Престижность Майклу Берру за указание моей ошибки!:)
Похоже, вам нужно переосмыслить свой код и изменить его для чего-то подобного.
Надеюсь, это поможет,
С наилучшими пожеланиями,
Том.
Ответ 7
Ваша первая идея может состоять в том, чтобы сделать что-то вроде этого:
void something(int a, int b=-1, int c=-1){
if(b == -1)
b = a;
if(c == -1)
c = b;
}
Я использовал -1, потому что эта функция работает только с положительными значениями. Но что, если кто-то использует мой класс и совершает ошибку, которая заканчивается отправкой -1 методу? Он все равно будет компилироваться и выполняться, но результат будет непредсказуем для пользователя. Поэтому разумной задачей было бы удалить любой аргумент по умолчанию и вместо этого создать кучу методов с таким же именем, как это:
void something(int a, int b, int c){
/* Do something with a, b and c */
}
void something(int a){
something(a, a, a);
}
void something(int a, int b){
something(a, b, b);
}
На код не требуется намного больше времени, и если кто-то использует его в программном интерфейсе с функциями автозаполнения, он покажет 3 возможных прототипа.