Сөздүк типтер: optional, variant жана tuple
"Балким маани бар", "бир нече типтин бири" жана топтоо үчүн типтик-коопсуз каражаттар
union - ушундайча алмаштырат.
- бар же жок болушу мүмкүн маани үчүн
std::optional<T>колдонуу, - эмне сактаарын дайыма билген типтик-коопсуз бирикме катары
std::variant<A, B, ...>колдонуу, std::pairжанаstd::tupleменен бир нече маанини топтоо,- алардын каалаганын структуралык байланыштар менен таза чечмелеп алуу.
Бул тема сиз курстун мурунку бөлүмдөрүнөн шаблондорду, шилтемелерди жана жылдыруу семантикасын жакшы билесиз деп болжолдойт. Бардык мисалдар C++17 компилятору менен компиляцияланат.
1. std::optional - балким маани
Функцияга көбүнчө "мына натыйжа" же "натыйжа жок" деп айтуу керек. Муну билдирүүнүн эски жолдорунун баары ишенимсиз: -1 сыяктуу сыйкырдуу белги кайтаруу (эгер -1 туура жооп болсочу?), bool кайтарып, чыныгы жоопту чыгаруу параметри аркылуу жазуу, же nullptr болушу мүмкүн таза көрсөткүч кайтаруу (аны ким ээлейт?). std::optional<T> (<optional> ичинен) "жоктукту" толук укуктуу, типтик-текшерилген абалга айлантат.
optional<T> же T камтыйт, же бош болот. Аны bool сыяктуу текшересиз, маанини * же -> аркылуу окуйсуз (маани бар кезде гана) жана value_or аркылуу кошумча вариант бересиз. Бош абал std::nullopt деп жазылат.
#include <optional>
#include <string>
using namespace std;
optional<int> parsePort(const string& scheme) {
if (scheme == "http") return 80;
if (scheme == "https") return 443;
return nullopt; // кайтара турган акылга сыярлык маани жок
}
Чакырган тарап текшерүүнү унута албайт, анткени маани optional ичинде жайгашкан жана аны адегенде ачуу керек:
auto p = parsePort("https");
if (p) { // маани барбы?
cout << "port = " << *p << "\n"; // коопсуз: биз текшердик
}
int port = parsePort("ftp").value_or(-1); // бош болсо кошумча вариант
* же -> аркылуу окуу - бул нөл көрсөткүчтү окугандай эле аныкталбаган жүрүм-турум. Дайыма адегенде текшериңиз же value_or колдонуңуз. Эгер өзгөчө кырдаалды каалсаңыз, .value() чакырыңыз, ал бош болгондо std::bad_optional_access ыргытат.