¿Qué dice la declaración
return {};
en C ++ 11 indique, y cuándo usarlo en lugar de (decir)
return NULL;
o
return nullptr;
¿Qué dice la declaración
return {};
en C ++ 11 indique, y cuándo usarlo en lugar de (decir)
return NULL;
o
return nullptr;
return;sin valor?return;Por otro lado,return{};es válido si tiene un tipo de retorno.Respuestas:
return {};indica "devolver un objeto del tipo de retorno de la función inicializado con un inicializador de lista vacío ". El comportamiento exacto depende del tipo de objeto devuelto.De cppreference.com (debido a que el OP está etiquetado como C ++ 11, excluí las reglas en C ++ 14 y C ++ 17; consulte el enlace para obtener más detalles):
Antes de C ++ 11, para una función que devuelve un
std::string, habría escrito:Usando la sintaxis de llaves en C ++ 11, no es necesario repetir el tipo:
return NULLyreturn nullptrdebe usarse cuando la función devuelve un tipo de puntero:Sin embargo,
NULLestá en desuso desde C ++ 11 porque es solo un alias para un valor entero (0), mientras quenullptres un tipo de puntero real:fuente
Probablemente esto sea confuso:
Probablemente esto no sea:
fuente
initializer_listconstructor, ¿no se usaría si no hay un constructor predeterminado disponible?return {}NO es equivalente areturn SomeObjectWithADefaultConstructor{};return {};significa que{}es el inicializador del valor de retorno . El valor de retorno se inicializa con una lista vacía.Aquí hay algunos antecedentes sobre el valor de retorno , basado en [stmt.return] en el estándar C ++:
Para una función que devuelve por valor (es decir, el tipo de retorno no es una referencia ni tampoco
void), hay un objeto temporal llamado valor de retorno . Este objeto es creado por elreturndeclaración y sus inicializadores dependen de lo que estaba en la declaración de retorno.El valor de retorno sobrevive hasta el final de la expresión completa en el código que llamó a la función; si tiene un tipo de clase, entonces su destructor se ejecutará a menos que su vida útil se extienda por el llamador vinculando una referencia directamente a él.
El valor de retorno se puede inicializar de dos formas diferentes:
return some_expression;- el valor de retorno se copia-inicializa desdesome_expressionreturn { possibly_empty_list };- el valor de retorno se inicializa por lista de la lista.Suponiendo que
Tes el tipo de retorno de la función, tenga en cuenta quereturn T{};es diferente areturn {}: en el primero,T{}se crea un temporal , y luego el valor de retorno se inicializa con copia a partir de ese temporal.Esto no se podrá compilar si
Tno tiene un constructor de copia / movimiento accesible, peroreturn {};tendrá éxito incluso si esos constructores no están presentes. En consecuencia,return T{};puede mostrar efectos secundarios del constructor de copia, etc., aunque este es un contexto de elisión de copia, por lo que puede que no.Aquí hay un breve resumen de la inicialización de lista en C ++ 14 (N4140 [dcl.init.list] / 3), donde el inicializador es una lista vacía:
Tes un agregado, entonces cada miembro se inicializa a partir de su inicializador de llaves o igual si tuviera uno, de lo contrario, como por{}(así que aplique estos pasos de forma recursiva).Tes un tipo de clase con un constructor predeterminado proporcionado por el usuario, ese constructor se llama.Tes un tipo de clase con un= defaultconstructor predeterminado definido implícitamente o ed, el objeto se inicializa en cero y luego se llama al constructor predeterminado.Tes astd::initializer_list, el valor de retorno es una lista de este tipo vacía.Tes decir, es un tipo que no es de clase; los tipos de retorno no pueden ser matrices), el valor de retorno se inicializa en cero.fuente
{}, que puede ser o no value-init.Es una especie de abreviatura para una nueva instancia del tipo de retorno de métodos.
fuente