Мазмунга өтүү

Сөздүк типтер: optional, variant жана tuple

Сабактын башталышы

Сөздүк типтер: optional, variant жана tuple

"Балким маани бар", "бир нече типтин бири" жана топтоо үчүн типтик-коопсуз каражаттар

Негизги идея: Стандарттык китепканада сансыз реалдуу китепканалардын сигнатураларында кездешкен бир нече чакан, жалпы максаттагы типтер бар. Аларды сөздүк типтер деп аташат, анткени алар маалыматтын кеңири таралган формалары үчүн жалпы сөздүк берет: "балким жок болушу мүмкүн маани", "бир нече типтин бири болгон маани" жана "бир нече маанинин туруктуу топтому". Заманбап C++ эски, катага жакын ыкмаларды - белги-маанилерди, чыгаруу параметрлерин жана таза 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);  // бош болсо кошумча вариант
Бош optional'ду * же -> аркылуу окуу - бул нөл көрсөткүчтү окугандай эле аныкталбаган жүрүм-турум. Дайыма адегенде текшериңиз же value_or колдонуңуз. Эгер өзгөчө кырдаалды каалсаңыз, .value() чакырыңыз, ал бош болгондо std::bad_optional_access ыргытат.

Бул сабакты YourAIZone платформасында улантыңыз

Толук сабакта — толук түшүндүрмө, чыгарылган мисалдар, көп кездешкен каталар, заматта текшерилүүчү тесттер жана ЖИ-репетитор. Конок катары дароо баштаңыз же прогрессти сактоо үчүн аккаунт түзүңүз.

Толук сабакта

  • Толук түшүндүрмө
  • Чыгарылган мисалдар
  • Көп кездешкен каталар жана алардан кантип качуу керек
  • Тест суроолору: 15
  • Тема боюнча суроолорго жооп берген ЖИ-репетитор
  • Окуучу, ата-эне жана мугалим үчүн прогрессти көзөмөлдөө