O exemplo mais simples que consigo pensar:
std::optional<int> try_parse_int(std::string s)
{
//try to parse an int from the given string,
//and return "nothing" if you fail
}
A mesma coisa pode ser realizada com um argumento de referência (como na assinatura a seguir), mas o uso std::optional
torna a assinatura e o uso mais agradáveis.
bool try_parse_int(std::string s, int& i);
Outra maneira de fazer isso é especialmente ruim :
int* try_parse_int(std::string s); //return nullptr if fail
Isso requer alocação dinâmica de memória, preocupação com propriedade etc. - sempre prefira uma das outras duas assinaturas acima.
Outro exemplo:
class Contact
{
std::optional<std::string> home_phone;
std::optional<std::string> work_phone;
std::optional<std::string> mobile_phone;
};
É extremamente preferível ter algo como a std::unique_ptr<std::string>
para cada número de telefone! std::optional
fornece a localização dos dados, o que é ótimo para o desempenho.
Outro exemplo:
template<typename Key, typename Value>
class Lookup
{
std::optional<Value> get(Key key);
};
Se a pesquisa não tiver uma determinada chave, podemos simplesmente retornar "sem valor".
Eu posso usá-lo assim:
Lookup<std::string, std::string> location_lookup;
std::string location = location_lookup.get("waldo").value_or("unknown");
Outro exemplo:
std::vector<std::pair<std::string, double>> search(
std::string query,
std::optional<int> max_count,
std::optional<double> min_match_score);
Isso faz muito mais sentido do que, digamos, ter quatro sobrecargas de função que usam todas as combinações possíveis de max_count
(ou não) e min_match_score
(ou não)!
Ele também elimina o maldito "passe -1
para max_count
se você não quiser um limite" ou "passe std::numeric_limits<double>::min()
para min_match_score
se você não quiser uma pontuação mínima"!
Outro exemplo:
std::optional<int> find_in_string(std::string s, std::string query);
Se a string de consulta não estiver inserida s
, desejo "não int
" - não qualquer valor especial que alguém decida usar para esse fim (-1?).
Para exemplos adicionais, você pode consultar a boost::optional
documentação . boost::optional
e std::optional
será basicamente idêntico em termos de comportamento e uso.