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

По ненаписанным параметрам для функций С++

Ниже приведен совершенно законный код C++

void foo (int) {
    cout << "Yo!" << endl;
}

int main (int argc, char const *argv[]) {
    foo(5); 
    return 0;
}

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

Зачем это законно начинать?

4b9b3361

Ответ 1

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

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

Существует также специальный случай для определяющий ваши собственные операторы пост-инкремента и пост-декремента: они должны иметь подпись с int, но этот параметр всегда не используется. Однако это соглашение граничит с взломом в оформлении языка.

Ответ 2

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

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

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

Ответ 3

Я просто хочу добавить, что иногда существует разница, называете ли вы параметр или нет. Например, компилятор рассматривает именованное значение rvalue как lvalue и неназванное значение rvalue как rvalue.

// named-reference.cpp  
// Compile with: /EHsc  
#include <iostream>  
using namespace std;

// A class that contains a memory resource.  
class MemoryBlock  
{  
   // TODO: Add resources for the class here.  
};

void g(const MemoryBlock&)   
{  
   cout << "In g(const MemoryBlock&)." << endl;  
}

void g(MemoryBlock&&)   
{  
   cout << "In g(MemoryBlock&&)." << endl;  
}

MemoryBlock&& f(MemoryBlock&& block)  
{  
   g(block);  
   return block;  
}  

int main()  
{  
   g(f(MemoryBlock()));  
}  

В этом примере создается следующий вывод:

В g (const MemoryBlock &).
В g (MemoryBlock &).

В этом примере основная функция передает rvalue на f. Тело f обрабатывает свой именованный параметр как lvalue. Вызов от f до g связывает параметр с ссылкой на lvalue (первая перегруженная версия g).