2010-06-30 17 views
22

Ho una funzione,C++ Argomento predefinito per il vettore <int> &?

void test(vector<int>& vec); 

Come posso impostare l'argomento di default per vec? Ho provato

void test(vector<int>& vec = vector<int>()); 

Ma c'è un avvertimento "estensione non standard utilizzata: 'argomento di default': conversione da 'std :: vector < _Ty>' a 'std :: vector < _Ty> &'"

C'è un modo migliore per farlo? Invece di

void test() { 
    vector<int> dummy; 
    test(dummy); 
} 

saluti, Voteforpedro

risposta

43

Hai provato:

void test(const vector<int>& vec = vector<int>()); 

C++ non permette provvisori di essere vincolato ai riferimenti non-const.

Se si ha realmente bisogno di avere uno vector<int>& (non uno const), è possibile dichiarare un'istanza statica e utilizzarlo come valore predefinito (quindi non temporaneo).

static vector<int> DEFAULT_VECTOR; 

void test(vector<int>& vec = DEFAULT_VECTOR); 

Ma attenzione, perché DEFAULT_VECTOR sarà (può) essere modificato e non si ripristinerà su ogni chiamata! Non sono sicuro che questo sia ciò che vuoi veramente.


Grazie alla stinky472, ecco un thread-safe alternativa:

Invece di fornire un valore di default, si potrebbe anche sovraccaricare test() con una versione zero parametro che definisce l'altra versione:

void test() 
{ 
    vector<int> vec; 
    test(vec); 
} 
+4

+1 ma penso che si dovrebbe sottolineare che "test" non sarebbe generalmente thread-safe se fosse stato modificato questo "DEFAULT_VECTOR". Potrebbe essere noioso, ma consiglio vivamente di scrivere due funzioni per tali esigenze (si può riutilizzare l'altra): void test() {vector temp; prova (temperatura); } – stinky472

+0

@ stinky472: Grazie, ho aggiornato la mia risposta. – ereOn

+1

Come nota a margine, esiste un modo hacky per ottenere un riferimento a un riferimento temporaneo se è possibile utilizzare un metodo su quest'ultimo che restituisce tale riferimento a se stesso ... ad es. '' Operatore =. Quindi, 'void test (vector & vec = vector () .operator = (vector ()));' dovrebbe funzionare (la durata del temporaneo non è influenzata qui e rimarrà sufficiente per gestire la chiamata). Ma per favore non farlo :) –

7

Trovo discutibile che un argomento di riferimento non const abbia un valore predefinito. Cosa dovrebbe significare?

Comunemente, una funzione che prende un riferimento non const significa "Potrei cambiare l'argomento". Se l'argomento è opzionale perché non passare un puntatore (non const)? In questo modo, quando i chiamanti non vogliono passare argomenti, possono passare NULL.
(Vedi here per ulteriori informazioni su come passare argomenti delle funzioni.)

Edit: Bene, e, naturalmente, c'è anche sovraccarico. Basta aggiungere un altro overload che non accetta questo argomento.

+0

Lo trovi in ​​modo discutibile? – Puppy

+3

@DeadMG: Ti stai riferendo al mio sottosistema di grammatica rotto? – sbi

+1

Farei qualcosa del genere? – Puppy

3

Impossibile inizializzare i riferimenti mutabili ai provvisori. Solo i riferimenti const consentono questo.Che cosa siete dopo è probabilmente questo:

void test(const vector<int>& vec = vector<int>()); 

Oltre a evitare un comportamento indefinito, questo rende più senso logico e da una prospettiva const correttezza. Se si desiderava che "test" modificasse il vettore originale che gli è stato passato, non sarebbe stato possibile fornire sensibilmente un valore predefinito. Quindi è ovvio che stai usando 'vec' qui per scopi di sola lettura e dovresti quindi renderlo un riferimento const.

+2

Non è possibile inizializzare i riferimenti mutabili ai provvisori direttamente, punto. Un temporaneo non si legherà a un reference-to-non-const: se lo provi, non è U.B., è un input non corretto (cioè errore del compilatore). VC++ ti consente di farlo, ma giustamente osserva che si tratta di un'estensione di linguaggio. –

+0

@Pavel ah buon punto! Ho visto brutti compilatori che hanno permesso questo comportamento come MSVC e versioni precedenti di CodeWarrior in cui il codice è stato creato ma si è bloccato. Modificherò il post di conseguenza per la precisione. Grazie per segnalarlo. – stinky472

-1

So che questa domanda è stato chiesto nel 2010, ma per il C++ 11 si può fare in questo modo:

void test(vector<int>& vec = {}) { 
     // Awesome code here 
} 

Come sottolineato in this answer.

+0

Ha lo stesso significato di 'void test (vector & vec = vector ());' come nella domanda, che è illegale a causa del tentativo di associare un riferimento temporaneo a un riferimento non const. Nella risposta a cui si collega, non è un riferimento. –

Problemi correlati