Найпростіший приклад, про який я можу придумати:
std::optional<int> try_parse_int(std::string s)
{
//try to parse an int from the given string,
//and return "nothing" if you fail
}
Те ж саме може бути зроблено замість аргументу посилань (як у наступному підписі), але використання std::optionalробить підпис та використання приємнішими.
bool try_parse_int(std::string s, int& i);
Ще один спосіб, що це можна зробити, особливо поганий :
int* try_parse_int(std::string s); //return nullptr if fail
Це вимагає динамічного розподілу пам’яті, турбуватися про право власності тощо - завжди віддайте перевагу одному з інших двох підписів, поданих вище.
Ще один приклад:
class Contact
{
std::optional<std::string> home_phone;
std::optional<std::string> work_phone;
std::optional<std::string> mobile_phone;
};
Це надзвичайно бажано, а не мати щось на зразок std::unique_ptr<std::string>для кожного номера телефону! std::optionalдає вам локальність даних, що чудово підходить для роботи.
Ще один приклад:
template<typename Key, typename Value>
class Lookup
{
std::optional<Value> get(Key key);
};
Якщо в пошуку немає певного ключа в ньому, ми можемо просто повернути "немає значення".
Я можу використовувати це так:
Lookup<std::string, std::string> location_lookup;
std::string location = location_lookup.get("waldo").value_or("unknown");
Ще один приклад:
std::vector<std::pair<std::string, double>> search(
std::string query,
std::optional<int> max_count,
std::optional<double> min_match_score);
Це має набагато більше сенсу, ніж, скажімо, наявність чотирьох функціональних перевантажень, які приймають усі можливі комбінації max_count(чи ні) та min_match_score(чи ні)!
Він також усуває в проклятий «Pass -1для , max_countякщо ви не хочете межі» або «Passstd::numeric_limits<double>::min() для min_match_scoreякщо ви не хочете , мінімальний бал»!
Ще один приклад:
std::optional<int> find_in_string(std::string s, std::string query);
Якщо рядок запиту відсутній s, я хочу "ні int" - ні б особливе значення хтось вирішив використовувати для цієї мети (-1?).
Для додаткових прикладів ви можете подивитися boost::optional документацію . boost::optionalі std::optionalв основному будуть ідентичними за поведінкою та використанням.