Почему С++ не позволяет использовать параметры функции для значений по умолчанию последних параметров?

Это продолжение этого вопроса. Код в вопросе ОП показался мне вполне разумным и недвусмысленным. Почему С++ не позволяет использовать прежние параметры для определения значений по умолчанию для последних параметров, например:

int foo( int a, int b = a );

Кроме того, по крайней мере, в С++ 11 объявленные типы параметров могут использоваться для определения типа возвращаемого значения, поэтому нередко можно использовать параметры функции аналогичным образом:

auto bar( int a ) -> decltype( a );

Таким образом, вопрос: каковы причины, по которым вышеуказанное объявление foo не разрешено?


person Michael    schedule 30.07.2015    source источник
comment
Одна из причин, о которой я могу думать, заключается в том, что для нормального функционирования потребовалось бы ограничение на порядок оценки аргументов функции, который в настоящее время не определен в C++. Это не требуется для примера возвращаемого типа.   -  person MooseBoys    schedule 30.07.2015
comment
Помимо удобства, если вы можете добавить ситуацию, когда это не достижимо с помощью перегрузки, как отвечает другой вопрос, это значительно подстегнёт необходимость. Без необходимости и обратной совместимости комитет по стандартам несколько консервативен в добавлении функций. Они склонны держаться подальше, почему бы и нет? в пользу гораздо более строгого почему.   -  person WhozCraig    schedule 30.07.2015
comment
В качестве примечания: два самых популярных соглашения о вызовах, используемых в C++ (__cdecl и __stdcall) определить порядок передачи аргументов справа налево. Если вы отлаживаете код с некоторыми нетривиальными (содержащими пользовательские конструкторы) параметрами в качестве аргументов функции и переходите к такому вызову, вы заметите, что конструкторы действительно вызываются в обратном порядке.   -  person Mateusz Grzejek    schedule 30.07.2015
comment
@Mateusz: соглашение о вызовах определяет пространственный порядок аргументов, а не временной порядок, в котором они построены. И совершенно не проблема придерживаться пространственного порядка, но использовать для построения совершенно другой временной порядок. Вы можете видеть, что временной порядок соответствует указанному пространственному порядку в сборках отладки просто потому, что автор компилятора решил создать параметры в этом порядке. Это не означает, что это будет справедливо и для выпускных сборок, и это, конечно, не означает, что компилятор должен использовать этот порядок.   -  person Paul Groke    schedule 30.07.2015
comment
@MooseBoys Именно потому, что порядок оценки в настоящее время не указан, не будет проблем с разрешением функции, которая наложит частичные ограничения на порядок оценки. Так что это не может быть причиной. Я думаю, как написал WhozCraig: это было запрещено, потому что для этого не было достаточных оснований.   -  person Paul Groke    schedule 30.07.2015


Ответы (1)


Во-первых, это потребовало бы, чтобы a оценивалось перед b, но C++ (как и C) не определяет порядок вычисления параметров функции.

Вы все еще можете получить желаемый эффект, добавив перегрузку:

int foo(int a, int b)
{ /* do something */ }

int foo(int a)
{ return foo(a, a); }
person Bo Persson    schedule 30.07.2015
comment
Я не понимаю, как это важно, что С++ не указывает порядок оценки. Разрешение использования параметров в более поздних значениях по умолчанию, конечно, наложит некоторый частичный порядок при использовании этой функции. Но я не вижу, как это может быть проблемой. Я думаю, что причина, по которой это не разрешено, заключается в том, что выгода будет слишком маленькой. - person Paul Groke; 30.07.2015