Подтвердить что ты не робот

Параметр по умолчанию C/С++, заданный как предыдущий аргумент

Мне не удалось найти четкого ответа на это, хотя это может быть связано с тем, что я не использовал правильные условия поиска, поэтому, пожалуйста, перенаправьте меня, если это так. Можно ли использовать предыдущие аргументы в списке параметров функций как значение по умолчанию для более поздних аргументов в списке параметров? Например,

void f( int a, int b = a, int c = b );

Если это возможно, существуют ли какие-либо правила использования? Любая разница между C и С++?

4b9b3361

Ответ 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 возможных прототипа.