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

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

SFINAE жана чектөөлөр

Перегрузкаларды типтер боюнча тандоо: enable_if, tag dispatch, аныктоо идиомасы жана концепттер эмнени оңдогону

Негизги идея: SFINAE - бул Substitution Failure Is Not An Error (алмаштыруудагы каталык - каталык эмес). Компилятор функциянын шаблонун инстанцирлөөгө аракет кылганда жана алмаштырылган типтер туура эмес сигнатура берсе, ал талапкер компиляцияны токтотпостон, перегрузкалардын топтомунан унчукпай алынып салынат. Ушул тынч алып салуу гана типтер чын эле колдогон типтер үчүн гана катышкан шаблондорду жазууга мүмкүндүк берет - C++17де компиляция учурундагы диспетчерлөөнүн негизи.
Теманын аягында сиз:
  • алмаштыруудагы каталык эмне экенин жана SFINAE так кайда иштээрин ("түз контекстте") түшүндүрө аласыз,
  • шаблондорду std::enable_if аркылуу чектей аласыз - кайтаруу тибинде, шаблон параметринде же жарыяланбаган мааниси боюнча параметрде,
  • тип трейттери боюнча компиляция учурунда tag dispatch менен диспетчерлей аласыз,
  • "бул тип X колдойбу?" деген суроону аныктоо идиомасы (void_t) менен бере аласыз,
  • SFINAEнин чыныгы чектөөлөрүн атай аласыз жана эмне үчүн C++20 концепттери аны алмаштырарын түшүнөсүз.

1. Перегрузканы чечүү жана алмаштыруу

Компилятор талапкер функциялардан перегрузкалар топтомун түзүп, андан кийин эң мыкты дал келүүнү тандаарын сиз билесиз. Функция шаблондору үчүн адегенде кошумча кадам бар: компилятор конкреттүү талапкерди түзүү үчүн чыгарылган шаблон аргументтерин шаблондун сигнатурасына алмаштырышы керек. SFINAE ушул алмаштыруу кадамында жашайт.

Алмаштыруу сигнатуранын түз контекстинде - кайтаруу тиби, параметрлер тизмеси же шаблон параметрлеринин тизмеси - туура эмес тип же туюнтма жаратканда, бул каталык эмес. Талапкер жөн гана алынып салынат, ал эми перегрузканы чечүү калган талапкерлер менен уланат.

// Эки перегрузка. Алмаштыруу кайсынысы *каралаарын* чечет.
template <typename T>
typename T::value_type first(const T& c) { return *c.begin(); }  // T::value_type керек

int first(int x) { return x; }                                   // жөнөкөй запастагы вариант

first(std::vector<int>{1,2});  // vectorдо ::value_type бар -> шаблон тандалды
first(42);                     // intте ::value_type жок -> шаблон унчукпай алынды,
                               //   int перегрузкасы колдонулат. Компиляция катасы жок.

"каталык эмес" деген сөз айкашы - маңызы ушул: эгер бул катуу каталык болсо, шаблон перегрузкасын кошуу байланышсыз чакырууларды бузмак. Анын ордуна ийгиликсиз алмаштыруу жөн гана талапкерлердин тизмесин кыскартат.

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

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

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

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