seconda - thinking in c++ volume 2 italiano




Perché una funzione senza identificatori di argomento è valida in C++? (4)

Data una funzione in C ++ con argomenti che sono solo tipi e non hanno identificatori,

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

Posso chiamarlo come tale:

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

Perché questo è un costrutto valido in C ++? È solo un'idiosincrasia del C ++, o questo tipo di dichiarazione ha effettivamente qualche scopo? Possiamo effettivamente accedere agli argomenti che sono stati passati in qualche modo? (Questo tipo di dichiarazione del metodo non funzionerà in Java.)


È legale e se ti stai chiedendo perché:

In genere, gli argomenti senza nome derivano dalla semplificazione del codice o dalla pianificazione anticipata delle estensioni. In entrambi i casi, lasciare l'argomento in posizione, sebbene inutilizzato, garantisce che i chiamanti non siano interessati dal cambiamento.

Estratto da: Bjarne Stroustrup. "Il linguaggio di programmazione C ++, quarta edizione."


Considera un caso in cui ti viene richiesto di fornire una funzione che soddisfi il seguente prototipo

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

E dire che stai operando in uno spazio 2D e non usare z all'interno della tua implementazione. Puoi

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

e basta ignorare z , ma il compilatore probabilmente vedrà che hai definito ma non usato z e ti avverto che potresti commettere un errore. Invece puoi

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

e tralasciare la definizione di z . Il compilatore accetterà e scarterà silenziosamente il terzo parametro perché sa che non lo vuoi.

Non vuoi semplicemente disattivare l'avviso a causa di errori come questo

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

Dove un indice di loop con un nome non valido ombreggia il parametro z . L'input del chiamante è ora ignorato e questo potrebbe avere conseguenze negative. Questo errore è spesso difficile da individuare con il bulbo oculare 1, specialmente se la z locale è sepolta da qualche parte in profondità in una funzione complessa.

Ogni volta che il compilatore può scegliere un possibile errore nel codice, approfittane. Significa meno lavoro per te.


L'idea è che potrebbe essere necessario modificare la definizione della funzione per utilizzare il segnaposto in un secondo momento, senza modificare tutto il codice in cui viene chiamata la funzione.

Gli argomenti in una dichiarazione di funzione possono essere dichiarati senza identificatori. Quando vengono utilizzati con argomenti predefiniti, può sembrare un po 'divertente. Puoi finire con:

void f(int x, int = 0, float = 1.1);

In C ++ non hai bisogno di identificatori nella definizione della funzione, o:

void f(int x, int, float flt) { /* ... */ }

Nel corpo della funzione, x e flt possono essere referenziati, ma non l'argomento centrale, perché non ha nome. Le chiamate di funzione devono comunque fornire un valore per il segnaposto, tuttavia: f(1) o f(1,2,3.0) . Questa sintassi ti consente di inserire l'argomento come segnaposto senza usarlo.


È legale in C ++.

C ++ 11 n3337 standard 8.4.1 (p6) Definizioni delle funzioni:

Nota: i parametri non utilizzati non devono essere nominati. Per esempio,

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

C ++ 14 standard:

[8.3.5.11] Un identificatore può essere fornito facoltativamente come nome parametro; se presente in una definizione di funzione, nomina un parametro (talvolta chiamato "argomento formale"). [Nota: in particolare, i nomi dei parametri sono opzionali anche nelle definizioni di funzioni e nomi utilizzati per un parametro in diverse dichiarazioni e la definizione di una funzione non deve essere la stessa.]





syntax