c++ - una - return mas de un valor c
Devolver valor opcional con?: Operador (2)
Puede constexpr
explícitamente el retorno de algún valor en un std::optional
, y retroceder en el constexpr
std::nullopt
para el retorno sin valor.
std::nullopt
es una constante de tipostd::nullopt_t
que se usa para indicar un tipo opcional con estado no inicializado....
std::nullopt_t
es un tipo de clase vacío que se usa para indicar un tipo opcional con estado sin inicializar. En particular,std::optional
tiene un constructor connullopt_t
como un único argumento, que crea un opcional que no contiene un valor.
Con este enfoque, la cláusula verdadera de la llamada del operador ternario devuelve explícitamente un std::optional
con algún valor, por lo que el compilador puede deducir el parámetro de plantilla / tipo envuelto (en este ejemplo: int32_t
) del tipo del envoltorio suministrado valor, lo que significa que no necesita especificarlo explícitamente.
Aplicado a tu ejemplo:
return it != map.end() ? std::optional(it->second) : std::nullopt;
// alternatively
return it != map.end() ? std::make_optional(it->second) : std::nullopt;
A menudo necesito usar el tipo opcional para las funciones:
std::optional<int32_t> get(const std::string& field)
{
auto it = map.find(field);
if (it != map.end()) return it->second;
return {};
}
¿Hay una manera de devolver el valor opcional en una línea? por ejemplo, esto:
std::optional<int32_t> get(const std::string& field)
{
auto it = map.find(field);
return it != map.end() ? it->second : {};
}
resulta en el error
error: expected primary-expression before ''{'' token
return it != map.end() ? it->second : {};
^
return it != map.end() ? it->second : std::optional<int32_t>{};
debe hacer el truco
El compilador debe deducir el tipo de resultado de la expresión ternaria de los dos últimos operandos, pero no hay forma de que pueda deducir std::optional<int32_t>
de int32_t
y {}
.
int32_t
otro lado, int32_t
y std::optional<int32_t>
tienen el tipo común deseado std::optional<int32_t>
.
Dato curioso relacionado: puede evitar repetir el tipo con deducción de tipo de devolución automática:
auto get(const std::string& field)
{
auto it = map.find(field);
return it != map.end() ? it->second : std::optional<int32_t>{};
}
Dependiendo de la preferencia, por supuesto, también puede inferir el argumento de la plantilla para el std::optional
desde it->second
con decltype
para reducir aún más la repetición.