enable_if-mallit
Rajoita templateja perinteisellä tavalla
enable_if-mallit on ilmainen C++ Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/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.
Mikä enable_if on
std::enable_if on pieni tyyppipiirre, joka määrittelee type-jäsenen ehdollisesti. Kun ehto on tosi, tyyppi on olemassa; kun ehto on epätosi, ympäröivä malli poistetaan SFINAEn avulla.
- Sijaitsee tiedostossa
<type_traits>. - Se on klassinen työkalu mallien rajoittamiseen.
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
doubleIt(T v) { return v * 2; }
int main() {
std::cout << doubleIt(21) << '\n';
return 0;
}Näin se toimii
enable_if<Cond, T>::type on T vain, kun Cond on tosi. Jos ehto on epätosi, type-jäsentä ei ole, joten sijoitus epäonnistuu.
#include <iostream>
#include <type_traits>
int main() {
std::cout << std::boolalpha;
std::cout << std::is_same<std::enable_if<true, int>::type, int>::value << '\n';
return 0;
}enable_if paluutyypissä
Yleisin sijoituspaikka on paluutyyppi. Funktio on olemassa vain, kun ehto täyttyy.
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
half(T v) { return v / 2; }
int main() {
std::cout << half(5.0) << '\n';
return 0;
}enable_if malliparametrina
Toisessa tavassa enable_if sijoitetaan oletusarvoiseen malliparametriin, jolloin paluutyyppi säilyy selkeänä.
#include <iostream>
#include <type_traits>
template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
T triple(T v) { return v * 3; }
int main() {
std::cout << triple(4) << '\n';
return 0;
}enable_if_t-lyhenne
C++14 lisäsi aliaksen std::enable_if_t<Cond, T>, joten typename ...::type -rakenteen voi jättää pois.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, T>
negate(T v) { return -v; }
int main() {
std::cout << negate(8) << '\n';
return 0;
}Kahden ylikuormituksen yhdistäminen
Tarjotkaa toisiaan täydentävät ehdot, jotta täsmälleen yksi ylikuormitus on kelvollinen mille tahansa tyypille eikä tulkinnanvaraisuutta synny.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, const char*>
category() { return "integer"; }
template <typename T>
std::enable_if_t<!std::is_integral<T>::value, const char*>
category() { return "non-integer"; }
int main() {
std::cout << category<int>() << ' ' << category<double>() << '\n';
return 0;
}Ehtojen yhdistäminen
Käyttäkää loogisia operaattoreita tyyppipiirteiden arvoihin ilmaistaksenne monipuolisempia rajoituksia, kuten "kokonaisluku ja etumerkillinen".
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value, T>
magnitude(T v) { return v < 0 ? -v : v; }
int main() {
std::cout << magnitude(-12) << '\n';
return 0;
}Konstruktorin rajoittaminen
Voitte sijoittaa enable_if-määreen konstruktorin malliparametriin, jolloin konstruktoria voidaan käyttää vain yhteensopiville tyypeille.
#include <iostream>
#include <type_traits>
struct Wrapper {
int value;
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
Wrapper(T v) : value(static_cast<int>(v)) {}
};
int main() {
Wrapper w(42);
std::cout << w.value << '\n';
return 0;
}Oletusarvoisen malliparametrin sudenkuoppa
Kaksi ylikuormitusta, jotka eroavat toisistaan vain oletusarvoisen enable_if-malliparametrin osalta, tulkitaan uudelleenmäärittelyiksi. Antakaa niille eri muoto (sijoittakaa esimerkiksi toisen ehto paluutyyppiin).
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, void>
printKind() { std::cout << "int\n"; }
template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, void>
printKind() { std::cout << "float\n"; }
int main() {
printKind<int>();
printKind<double>();
return 0;
}Vertailu konsepteihin
C++20:n konseptit korvaavat suurimman osan enable_if-käytöstä paljon selkeämällä syntaksilla, mutta enable_if on edelleen välttämätön ennen C++20:tä tehdyssä koodissa ja joissakin erikoistapauksissa.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_arithmetic<T>::value, T>
square(T v) { return v * v; }
int main() {
std::cout << square(6) << ' ' << square(1.5) << '\n';
return 0;
}Täydellinen esimerkki
Yhdistäkää kaikki: funktioperhe, joka muotoilee kokonaisluvut ja liukuluvut eri tavoin ja jonka toteutus valitaan käännösaikana.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, void>
format(T v) { std::cout << "int[" << v << "]\n"; }
template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, void>
format(T v) { std::cout << "float(" << v << ")\n"; }
int main() {
format(10);
format(3.5);
return 0;
}Pikatarkistus
Testatkaa ymmärrystänne enable_if-rakenteesta.
Kertaus
Opitte klassiset enable_if-kaavat:
- määrittelee
::type-jäsenen vain, kun ehto on tosi, mikä mahdollistaa SFINAEn - sijoitetaan paluutyyppiin tai oletusarvoiseen malliparametriin
- käyttäkää
enable_if_t-aliasta ja yhdistäkää tyyppipiirteitä loogisilla operaattoreilla - konseptit korvaavat sen C++20:ssa, mutta sitä käytetään edelleen laajasti
Tämä päättää Template Specialization and SFINAE -kurssin.
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 ”enable_if-mallit” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa C++ Academy-oppimispolun 3 oppituntia, myös oppitunnin “enable_if-mallit”. 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 ”enable_if-mallit”?
Rajoita templateja perinteisellä tavalla 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 4/4.
Kuinka kauan ”enable_if-mallit”-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
- Täysi erikoistaminen
- Osittainen erikoistaminen
- SFINAE
- enable_if-mallit