El ejemplo más simple que se me ocurre:
std::optional<int> try_parse_int(std::string s)
{
//try to parse an int from the given string,
//and return "nothing" if you fail
}
Lo mismo podría lograrse con un argumento de referencia (como en la siguiente firma), pero el uso std::optional
hace que la firma y el uso sean más agradables.
bool try_parse_int(std::string s, int& i);
Otra forma de hacer esto es especialmente mala :
int* try_parse_int(std::string s); //return nullptr if fail
Esto requiere una asignación de memoria dinámica, preocuparse por la propiedad, etc. Siempre prefiera una de las otras dos firmas anteriores.
Otro ejemplo:
class Contact
{
std::optional<std::string> home_phone;
std::optional<std::string> work_phone;
std::optional<std::string> mobile_phone;
};
¡Esto es extremadamente preferible a tener algo como un std::unique_ptr<std::string>
para cada número de teléfono! std::optional
le brinda la localidad de datos, que es excelente para el rendimiento.
Otro ejemplo:
template<typename Key, typename Value>
class Lookup
{
std::optional<Value> get(Key key);
};
Si la búsqueda no tiene una clave determinada, simplemente podemos devolver "sin valor".
Puedo usarlo así:
Lookup<std::string, std::string> location_lookup;
std::string location = location_lookup.get("waldo").value_or("unknown");
Otro ejemplo:
std::vector<std::pair<std::string, double>> search(
std::string query,
std::optional<int> max_count,
std::optional<double> min_match_score);
¡Esto tiene mucho más sentido que, por ejemplo, tener cuatro sobrecargas de funciones que toman todas las combinaciones posibles de max_count
(o no) y min_match_score
(o no)!
¡También elimina el maldito "Pase -1
por max_count
si no quiere un límite" o "Pase std::numeric_limits<double>::min()
por min_match_score
si no quiere un puntaje mínimo"!
Otro ejemplo:
std::optional<int> find_in_string(std::string s, std::string query);
Si la cadena de consulta no está en s
, quiero "no int
", no cualquier valor especial que alguien haya decidido usar para este propósito (-1?).
Para ver ejemplos adicionales, puede consultar la boost::optional
documentación . boost::optional
y std::optional
básicamente será idéntico en términos de comportamiento y uso.