Что делает компилятор C ++ при получении неоднозначных параметров по умолчанию? - PullRequest
5 голосов
/ 04 октября 2010

Что делает компилятор C ++ при получении неоднозначных параметров по умолчанию? Например, скажем, была такая функция:

void function(int a = 0, float b = 3.1);
void function(int a, float b =1.1, int c = 0);

Считается ли вышесказанное неоднозначным? Если нет, то что делает компилятор (как точно соответствует функция) при вызове что-то вроде function1(10)?

Спасибо!

Ответы [ 4 ]

8 голосов
/ 04 октября 2010

Следующее нормально

void function(int a = 0, float b = 3.1);
void function(int a, float b =1.1, int c = 0);

И следующее тоже хорошо

function(); // calls first function

Но следующее неоднозначно

function(1); // second and first match equally well

Для разрешения перегрузки (процесс, который сообщает, какую функцию вызывать), параметры, которые не получили явных аргументов и которые используют аргументы по умолчанию, игнорируются. Таким образом, компилятор действительно видит две функции, обе из которых имеют один параметр int для указанного выше вызова, и не могут принять решение.

Хотя следующее плохо сформировано

void function(int a = 0, float b = 3.1);
void function(int a, float b =1.1);

Если для кода в вашем вопросе вы объявляете две функции (поскольку оба объявления имеют разное количество параметров), в этом примере вы объявляете только одну функцию. Но второе его объявление повторяет аргумент по умолчанию для параметра (и даже с другим значением, но это больше не имеет значения). Это не разрешено Обратите внимание, что следующее хорошо

void function(int a, float b = 3.1);
void function(int a = 0, float b);

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

void function(int a = 0, float b = 3.1);
void function1() {
  void function(int a, float b = 1.1); 
  function(0);
}

Вызывает функцию с 1.1, переданным для b.

1 голос
/ 04 октября 2010

Если у них разные имена (как в вашем примере), нет никакой двусмысленности.Если они имеют одинаковое имя (так что это попытка перегрузки), компилятор будет жаловаться.

Хотя оказывается, что вы можете переопределить аргументы по умолчанию для функции в другой области (это для меня новость...) - но в той же области вы не можете переопределить аргументы по умолчанию даже к тому же значению .из 8.3.6 / 4 «Аргументы по умолчанию»:

Для не шаблонных функций аргументы по умолчанию могут быть добавлены в более поздние объявления функции в той же области видимости.Объявления в разных областях имеют совершенно разные наборы аргументов по умолчанию.То есть объявления во внутренних областях не получают аргументы по умолчанию из объявлений во внешних областях и наоборот.В данном объявлении функции все параметры, следующие за параметром с аргументом по умолчанию, должны иметь аргументы по умолчанию, предоставленные в этом или предыдущих объявлениях.Аргумент по умолчанию не должен быть переопределен более поздним объявлением (даже с тем же значением).

0 голосов
/ 04 октября 2010

Более того, ответ на любой вопрос, начинающийся с «Что делает компилятор C ++ ...», всегда будет «Зависит от того, о каком компиляторе вы говорите».

0 голосов
/ 04 октября 2010

Неоднозначность?У вас есть две совершенно независимые разные функции: function1 и function2.Даже количество параметров в каждой функции отличается.Здесь нет никакой двусмысленности.Когда вы просите компилятор вызвать function1(10), он вызывает function1(10, 3.1).function2 даже не входит в картину.

Если бы это была одна и та же функция, проблема неоднозначности не возникла бы просто потому, что в C ++ недопустимо указывать аргумент по умолчанию для того же параметра большечем один раз (в пределах одной и той же единицы перевода).Даже если вы во второй раз укажете одно и то же значение аргумента по умолчанию, программа плохо сформирована

void foo(int a = 5);
void foo(int a = 5); // <- ERROR

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

...