C++ Academy · Oppitunti

Mallien erikoistaminen: osittainen ja täydellinen

Erikoista malleja tiettyjä tyyppejä ja osittaisia parametrikuvioita varten.

Oppitunti 2/414 vaihetta

Mallien erikoistaminen: osittainen ja täydellinen on ilmainen C++ Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu C++ Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C++ Academy-kurssilla on yhteensä 4 oppituntia.

Kun geneerinen muoto ei riitä

Joskus tietty tyyppi tarvitsee mukautetun toiminnan. Template-erikoistuksen avulla voitte tarjota tietylle argumentille räätälöidyn toteutuksen.

Täydellinen erikoistus

Määritelkää tarkat tyypit ja toteuttakaa kokonaan vaihtoehtoinen versio.

template <typename T>
struct Printer {
    void print(T x) { std::cout << x; }
};

template <>
struct Printer<bool> {
    void print(bool x) { std::cout << (x ? "true" : "false"); }
};

Erikoistuksen käyttäminen

Kääntäjä valitsee erikoistuksen automaattisesti, kun tyypit täsmäävät.

Printer<int>  pi;  pi.print(42);     // 42
Printer<bool> pb;  pb.print(true);   // true

Funktiotemplaten erikoistaminen

Voitte erikoistaa myös funktiotemplateja — mutta suosikaa ylikuormitusta. Ylikuormitukset toimivat paremmin yhdessä normaalien hakusääntöjen kanssa.

template <typename T> void f(T x) { /* general */ }
template <> void f<int>(int x) { /* int specific */ }

Miksi ylikuormituksia kannattaa suosia funktioiden erikoistamisen sijaan

Funktiotemplaten erikoistus ei osallistu ylikuormituksen ratkaisemiseen samalla tavalla. Ylikuormitukset ovat selkeämpiä ja välttävät ansan, jossa ihmetellään: "Miksi erikoistustani ei kutsuta?"

Osittainen erikoistus (vain luokat)

Osittaisen erikoistuksen avulla voitte mukauttaa toteutuksen tyyppiryhmälle — esimerkiksi osoittimille, viittauksille tai mille tahansa säilölle.

template <typename T>
struct Type { static const char* name() { return "general"; } };

template <typename T>
struct Type<T*> { static const char* name() { return "pointer"; } };

template <typename T>
struct Type<std::vector<T>> { static const char* name() { return "vector"; } };

Osittaisen erikoistuksen käyttötapaukset

Yleisiä tilanteita:

  • Osoitintyypeille tarvitaan erilainen toiminta
  • Triviaalisti kopioitaville tyypeille tarvitaan optimoitu versio
  • Säilökohtaiset ohitukset

std-templatien erikoistaminen

Voitte erikoistaa std-nimiavaruuden templateja (rajoituksin) — tavallisimmin std::hash-templatea käyttäjätyypeille, jotta niitä voidaan käyttää std::unordered_map-säilössä.

template <>
struct std::hash<MyType> {
    size_t operator()(const MyType& v) const {
        return /* compute hash */;
    }
};

Milloin erikoistusta kannattaa käyttää

Käyttäkää erikoistusta, kun:

  • Tyypille tarvitaan perusteellisesti erilainen toiminta
  • Tarvitsette tunnetuille tyypeille optimoituja koodipolkuja
  • Integroitte geneeriseen kirjastoon, joka käyttää tyyppipiirteitä

Nyky-C++:n vaihtoehdot

C++17 lisäsi if constexpr -rakenteen ja C++20 conceptit — molemmat korvaavat erikoistuksen usein selkeämmällä koodilla.

template <typename T>
void print(const T& x) {
    if constexpr (std::is_same_v<T, bool>) {
        std::cout << (x ? "true" : "false");
    } else {
        std::cout << x;
    }
}

Erikoistusten hierarkia

Kun useita erikoistuksia voisi soveltua, täsmällisin voittaa. Kääntäjä valitsee vaihtoehdon yksiselitteisesti — tai ilmoittaa virheestä.

Yleiset sudenkuopat

Kaksi yleistä sudenkuoppaa:

  • template <> -rakenteen unohtaminen täydellisestä erikoistuksesta
  • Erikoistusten sijoittaminen otsikkotiedostoihin ilman inline-määrettä, mikä johtaa ODR-rikkomuksiin

Pikatarkistus

Minkä tyyppinen erikoistus ei ole suoraan sallittu funktiotemplateille?

Kertaus

Template-erikoistus tarjoaa tyyppikohtaisia toteutuksia. Täydellinen erikoistus määrittää kaikki parametrit, kun taas osittainen erikoistus (vain luokkatemplateille) mukauttaa toteutuksen tyyppiryhmille. Nyky-C++:n vaihtoehdot, kuten if constexpr ja conceptit, tuottavat usein selkeämpää koodia.

Aloita maksutta

Opi C++ tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
51
Oppitunnit
203

Usein kysytyt kysymykset

Onko oppitunti ”Mallien erikoistaminen: osittainen ja täydellinen” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa C++ Academy-oppimispolun 3 oppituntia, myös oppitunnin “Mallien erikoistaminen: osittainen ja täydellinen”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. C++ Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Mallien erikoistaminen: osittainen ja täydellinen”?

Erikoista malleja tiettyjä tyyppejä ja osittaisia parametrikuvioita varten. Harjoittelet C++ Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni C++ Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin C++ Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”Mallien erikoistaminen: osittainen ja täydellinen”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä C++ Academy-oppitunnilla?

Kyllä. Jokainen C++ Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Funktio- ja luokkamallit uudelleen tarkasteltuna
  2. Mallien erikoistaminen: osittainen ja täydellinen
  3. Variadiset mallit ja parametripaketit
  4. constexpr-funktiot ja if constexpr
← Takaisin: C++ Academy