Почему переменные-члены не могут использоваться в качестве параметров по умолчанию? [дубликат]
Возможный дубликат:
нестатический член как аргумент по умолчанию нестатической функции-члена
Поправьте меня, если я ошибаюсь, но я думаю, что параметры по умолчанию работают следующим образом:
Когда компилятор видит вызов функции, он начинает толкать параметры в стек. Когда у него закончатся параметры, он начнет толкать значения по умолчанию в стек, пока не будут заполнены все необходимые параметры (я знаю, что это упрощение, так как параметры фактически перемещаются справа налево, поэтому он будет начинаться с значений по умолчанию, но идея та же).
Если это верно, то почему переменные-члены не могут использоваться по умолчанию? Мне кажется, что так как компилятор толкает их, как обычно, на сайте вызова, он должен быть в состоянии решить их просто отлично!
EDIT поскольку кажется, что ответы на мой вопрос были неправильно поняты, позвольте мне уточнить. Я знаю, что это так, и я знаю, что разрешено и не разрешено языком. Мой вопрос заключается в том, почему разработчики языка решили не допустить этого, поскольку это, кажется, естественно работает.
4 ответа:
Суть того, о чем вы просите, может быть изложена в этом простом примере
void foo(int a, int b = a);Это не допускается в C++. C++ не позволяет аргументам по умолчанию зависеть от других параметров.
Использование членов класса в качестве аргументов по умолчанию является лишь частным случаем вышеописанного, поскольку доступ к членам класса осуществляется через указатель
this, а указательthis-это просто еще один скрытый параметр каждой нестатической функции-члена.Итак, вопрос действительно в том, почему
void foo(int a, int b = a);Не является разрешено.
Одна из очевидных потенциальных причин для отказа в этом состоит в том, что это наложило бы дополнительные требования на порядок оценки аргументов. Как известно, в C++ порядок вычисления аргументов функции не определен-компилятор может вычислять аргументы в любом порядке. Однако для того, чтобы поддержать вышеупомянутую функциональность аргумента по умолчанию компилятор должен был бы убедиться, чтоaвычисляется передb. Это выглядит как чрезмерное требование, которое ограничивает типичное свобода порядка оценки, которую мы привыкли видеть в C++.Обратите внимание, что это
int a; void foo(int b = a);Допускается в C++. И, очевидно, он не демонстрирует вышеупомянутый порядок оценки вопроса.
Я считаю, что это наиболее подходящие абзацы из стандарта, особенно §9:
8.3.6 аргументы по умолчанию [dcl.ПКТ.default]
§7 локальные переменные не должны использоваться в аргументе по умолчанию§9 [...] Аналогичным образом, нестатический член не должен использоваться в аргументе по умолчанию, даже если он не вычисляется, если он не отображается как id-выражение выражения доступа к члену класса (5.2.5) или если он не используется для формирования указателя на член (5.3.1).
В этом посте перечислены все способы установки параметра по умолчанию - должны ли параметры функции по умолчанию быть постоянными в C++?
Нетрудно обойти вашу потребность.
class A { int a; public: void f(int i); void f() { f(a); } };Дает вам то, что вы хотите.
Резюмируя Наваз отличный ответ в связанном вопросе: вызов
void Foo::Bar(int a = this->member)действительно означаетvoid Foo__Bar(Foo* this, int a = this->member). Очевидно, что второй аргумент не может быть вычислен до первого, что нарушает аксиому C++, согласно которой компиляторы могут вычислять аргументы в любом порядке, который им нравится.