2010-06-30 22 views
22

Tengo una función,C++ Argumento predeterminado para el vector <int> &?

void test(vector<int>& vec); 

¿Cómo puedo establecer el argumento por defecto para vec? He tratado

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

Pero hay una advertencia de "extensión no estándar utilizado: 'argumento por defecto': la conversión de 'std :: vector < _Ty>' a 'std :: vector < _Ty> &'"

¿Hay una mejor manera de hacer esto? En lugar de

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

Saludos, Voteforpedro

Respuesta

43

¿Usted ha intentado:

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

C++ no permite a los temporales pueden unir a las referencias no const.

Si realmente necesita tener un vector<int>& (no un const uno), puede declarar una instancia estática y usarla como valor predeterminado (por lo tanto no temporal).

static vector<int> DEFAULT_VECTOR; 

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

Pero cuidado, porque se DEFAULT_VECTOR (puede) ser modificado y no se restablecerá en cada llamada! No estoy seguro de que esto sea lo que realmente quieres.


Gracias a stinky472, aquí es una alternativa segura para los subprocesos:

En lugar de proporcionar un valor por defecto, que también podría sobrecargar test() con una versión con parámetro cero que llama a la otra versión:

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

+1 pero creo que debería señalarse que 'prueba' generalmente no sería seguro para subprocesos si fuera a modificar este 'DEFAULT_VECTOR'. Puede ser tedioso, pero recomiendo escribir dos funciones para tales necesidades (una puede reutilizar la otra): prueba vacía() {vector temp; prueba (temperatura); } – stinky472

+0

@ stinky472: Gracias, actualicé mi respuesta. – ereOn

+1

Como nota al margen, hay una forma estrafalaria de obtener una referencia a un temporal si puede usar algún método en este último que devuelva dicha referencia a sí mismo ... p. 'operator ='. Por lo tanto, 'prueba vacía (vector y vec = vector () .operator = (vector ()));' debería funcionar (la duración del temporal no se ve afectada aquí y seguirá siendo suficiente para manejar la llamada). Pero por favor no lo hagas :) –

7

Encuentro cuestionable que un argumento de referencia que no sea const tenga un valor predeterminado. ¿Qué se supone que significa esto?

Comúnmente, una función que toma una referencia no const significa "Podría cambiar el argumento". Si el argumento es opcional ¿por qué no pasar un puntero (no const)? De esta forma, cuando las personas que llaman no quieran pasar un argumento, pueden pasar NULL.
(Ver here para obtener más información sobre cómo pasar argumentos de la función.)

Editar: Bueno, y por supuesto, también hay una sobrecarga . Simplemente agregue otra sobrecarga que no tome este argumento.

+0

¿Lo encuentras cuestionable? – Puppy

+3

@DeadMG: ¿Te refieres a mi subsistema de gramática rota? – sbi

+1

¿Haría algo así? – Puppy

3

No podemos inicializar las referencias mutables a los temporales. Solo las referencias const lo permiten.Lo que está después es más probable esto:

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

Aparte de evitar un comportamiento indefinido, esto tiene más sentido lógico y desde una perspectiva const-corrección. Si desea que 'prueba' modifique el vector original que se le está pasando, no habría podido proporcionar de manera sensata un valor predeterminado. Por lo tanto, es obvio que está utilizando 'vec' aquí para fines de solo lectura y por lo tanto, debe ser una referencia constante.

+2

No puede inicializar directamente las referencias mutables a los temporales, punto. Un temporal no se vinculará a una referencia-a-no-const - si lo intenta, no es U.B., es una entrada mal formada (es decir, error del compilador). VC++ le permite hacer esto, pero correctamente señala que es una extensión de idioma. –

+0

@Pavel ah buen punto! He visto desagradables compiladores que permiten este comportamiento como MSVC y versiones pasadas de CodeWarrior donde el código se compila pero se cuelga. Voy a modificar la publicación en consecuencia para la precisión. Gracias por mencionarlo. – stinky472

-1

Sé que esta pregunta se hizo en 2010, pero para C++ 11 puede hacerlo de esta manera:

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

Como se señaló en this answer.

+0

Tiene el mismo significado que 'prueba de vacío (vector & vec = vector ());' como en la pregunta, que es ilegal debido a intentar vincular una referencia temporal a una referencia no constante. En la respuesta a la que se vincula, no es una referencia. –

Cuestiones relacionadas