L'exemple le plus simple auquel je puisse penser:
std::optional<int> try_parse_int(std::string s)
{
//try to parse an int from the given string,
//and return "nothing" if you fail
}
La même chose peut être accomplie avec un argument de référence à la place (comme dans la signature suivante), mais l'utilisation std::optional
rend la signature et l'utilisation plus agréables.
bool try_parse_int(std::string s, int& i);
Une autre façon de procéder est particulièrement mauvaise :
int* try_parse_int(std::string s); //return nullptr if fail
Cela nécessite une allocation de mémoire dynamique, se soucier de la propriété, etc. - préférez toujours l'une des deux autres signatures ci-dessus.
Un autre exemple:
class Contact
{
std::optional<std::string> home_phone;
std::optional<std::string> work_phone;
std::optional<std::string> mobile_phone;
};
C'est extrêmement préférable à la place d'avoir quelque chose comme un std::unique_ptr<std::string>
pour chaque numéro de téléphone! std::optional
vous donne la localité des données, ce qui est idéal pour les performances.
Un autre exemple:
template<typename Key, typename Value>
class Lookup
{
std::optional<Value> get(Key key);
};
Si la recherche ne contient pas une certaine clé, nous pouvons simplement renvoyer «aucune valeur».
Je peux l'utiliser comme ceci:
Lookup<std::string, std::string> location_lookup;
std::string location = location_lookup.get("waldo").value_or("unknown");
Un autre exemple:
std::vector<std::pair<std::string, double>> search(
std::string query,
std::optional<int> max_count,
std::optional<double> min_match_score);
Cela a beaucoup plus de sens que, disons, avoir quatre surcharges de fonctions qui prennent toutes les combinaisons possibles de max_count
(ou non) et min_match_score
(ou pas)!
Il élimine également le maudit "Passer -1
pour max_count
si vous ne voulez pas de limite" ou "Passer std::numeric_limits<double>::min()
pour min_match_score
si vous ne voulez pas un score minimum"!
Un autre exemple:
std::optional<int> find_in_string(std::string s, std::string query);
Si la chaîne de requête n'est pas incluse s
, je veux "non int
" - pas la valeur spéciale que quelqu'un a décidé d'utiliser à cette fin (-1?).
Pour des exemples supplémentaires, vous pouvez consulter la boost::optional
documentation . boost::optional
et std::optional
sera fondamentalement identique en termes de comportement et d'utilisation.