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

Почему функция, не имеющая идентификаторов аргументов в С++?

Учитывая функцию в С++ с аргументами, которые являются только типами и не имеют идентификаторов,

 void foo1(int, int, int){cout << "called foo1";}

Я могу назвать это следующим:

int main()
{
    foo1(10, 10, 10);
}

Почему это допустимая конструкция в С++? Является ли это просто идиосинкразией С++ или действительно ли такая декларация имеет какую-то цель? Можем ли мы фактически получить доступ к аргументам, которые были переданы каким-то образом? (Этот вид объявления метода не будет работать на Java.)

4b9b3361

Ответ 1

Рассмотрим случай, когда вам необходимо предоставить функцию, которая соответствует следующему прототипу

void dostuff(int x, int y, int z);

И скажите, что вы работаете в 2D-пространстве и не используете z внутри своей реализации. Вы можете

void dostuff(int x, int y, int z)
{
    // use x and y
}

и просто игнорировать z, но компилятор, скорее всего, обнаружит, что вы определили, но не использовали z, и предупредите, что вы можете сделать ошибку. Вместо этого вы можете

void dostuff(int x, int y, int )
{
    // use x and y
}

и оставьте определение z. Компилятор будет принимать и молча отбрасывать третий параметр, потому что он знает, что вы этого не хотите.

Вы не хотите просто отключать предупреждение из-за ошибок, подобных этому

void dostuff(int x, int y, int z)
{
    for (int z = 0; z < MAX; z++)
    {
        // use x and y and z, the local z. 
    }
}

В тех случаях, когда индексированный индекс петли теряет параметр z. Ввод вызывающего абонента теперь игнорируется, и это может иметь плохие последствия. Эта ошибка часто бывает трудно заметить с помощью глазного яблока с отметкой 1, особенно если локальный z похоронен где-то глубоко в сложной функции.

В любое время, когда компилятор может выбрать возможную ошибку в вашем коде, воспользуйтесь преимуществом. Это означает, что вам будет меньше работы.

Ответ 2

Объявление типа

void foo1(int, int, int){cout << "called foo1";}

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

virtual void foo1(int something, int another, int andAnother) = 0;

НО вы не собираетесь использовать параметры, которые вам переданы.

Еще один пример: если вы хотите передать функцию, например, другая функция, которая ожидает указатель на функцию void с тремя параметрами int.

void giveMeFoo( void (*fn)(int, int, int) ) { ... }

Кроме того, более высокие уровни предупреждения вызывают предупреждение, если объявлены параметры, которые не оцениваются в теле функции. Вы можете избежать этого, оставив имена параметров далеко.

Параметры без имен тогда действительно недоступны в теле функции больше - специально. user4581301 хорошо описал, почему.

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

Ответ 3

Да. Это законно в С++.

С++ 11 n3337 стандарт 8.4.1 (p6) Определения функций:

Примечание. Невозможно назвать неиспользуемые параметры. Например,

void print(int a, int) {
    std::printf("a = %d\n", a);
}

Стандарт С++ 14:

[8.3.5.11] В качестве имени параметра может быть указан идентификатор; если он присутствует в определении функции, он называет параметр (иногда называемый "формальный аргумент" ). [Примечание: в частности, параметр имена также являются необязательными в определениях функций и именах, используемых для параметр в разных объявлениях и определение функции не обязательно должны быть одинаковыми.]

Ответ 4

Это законно, и если вам интересно, почему:

Как правило, неназванные аргументы возникают из-за упрощения кода или от планирования вперед для расширений. В обоих случаях аргумент на месте, хотя и не используется, гарантирует, что вызывающие повлиял на изменение.

Отрывок из: Bjarne Stroustrup. "Язык программирования С++, четвертое издание".