Почему существующие аргументы функции нельзя использовать для оценки других аргументов по умолчанию? - PullRequest
6 голосов
/ 05 февраля 2012

Я писал функцию foo(), которая принимает 2 const char* с в качестве аргументов, pBegin и pEnd. foo() передается строка с нулевым символом в конце. По умолчанию pEnd указывает на \0 (последний символ) строки.

void foo (const char *pBegin,
          const char *pEnd = strchr(pBegin, 0))  // <--- Error
{
  ...
}

Тем не менее, я получаю сообщение об ошибке в строке выше:

error: local variable ‘pBegin’ may not appear in this context

Почему компилятор не разрешает такую ​​операцию? В чем потенциальная проблема?

Ответы [ 4 ]

9 голосов
/ 05 февраля 2012

Стандарт не только явно запрещает использование других параметров в выражении аргумента по умолчанию, но также объясняет почему и приводит пример:

ИСО / МЭК 14882: 2003 (E) - 8.3.6 Аргументы по умолчанию [dcl.fct.default]

9. Аргументы по умолчанию оцениваются при каждом вызове функции. Порядок вычисления аргументов функции не указан. Следовательно, параметры функции не должны использоваться по умолчанию выражения аргумента, даже если они не оцениваются. Параметры функция, объявленная до того, как выражение аргумента по умолчанию находится в области видимости и может скрывать пространство имен и имена членов класса. [Пример:

    int a;
    int f(int a, int b = a);         // error: parameter a
                                     // used as default argument
    typedef int I;
    int g(float I, int b = I(2));    // error: parameter I found
    int h(int a, int b = sizeof(a)); // error, parameter a used
                                     // in default argument

- конец примера] ...

6 голосов
/ 05 февраля 2012

Язык по-прежнему предлагает способ делать то, что вы хотите - использовать перегруженные функции:

void foo (const char *pBegin, const char *pEnd)
{
   //...
}

void foo (const char *pBegin)
{ foo(pBegin, strchr(pBegin, 0)); }
3 голосов
/ 05 февраля 2012

Когда вызывается функция, оцениваются аргументы по умолчанию, но порядок их оценки не определяется стандартом C ++. Это означает, что вы не можете ссылаться на другие параметры в аргументе по умолчанию, поскольку они могут еще не иметь известного значения.

1 голос
/ 05 февраля 2012

Нельзя использовать локальную переменную в качестве значения аргумента по умолчанию.

Цитата отсюда:

Стандарт говорит нам, что аргумент по умолчанию - это просто выражение. Есть некоторые вещи, которые не разрешены (использование локальных переменных, использование ключевое слово «это») но по умолчанию все остальное может служить по умолчанию аргумент.

...