Найпростіший приклад, про який я можу придумати:
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
в основному будуть ідентичними за поведінкою та використанням.