std::move ja std::forward
Muunna lvaluet rvalueiksi std::movella ja säilytä arvokategoria std::forwardilla.
std::move ja std::forward on ilmainen C++ Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/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.
Kaksi sukulaista, eri tehtävät
std::move ja std::forward ovat molemmat käännösaikaisia tyyppimuunnoksia. Ne näyttävät samanlaisilta, mutta ratkaisevat eri ongelmia.
std::move: muunna aina rvalue-arvoksi
std::move(x) muuntaa x:n ehdoitta rvalue-viittaukseksi. Vastaanottava funktio voi tällöin varastaa sen resurssit.
std::string s = "Hello";
std::string t = std::move(s); // move-constructs t from s
// s is now in a valid-but-unspecified stateMilloin move-funktiota käytetään
Käyttäkää std::move-funktiota seuraavissa tilanteissa:
- siirtorakentajissa ja siirtosijoitusoperaattoreissa
- palautettaessa paikallinen muuttuja, kun siirto halutaan pakottaa (harvoin tarpeen — RVO yleensä toteutuu)
- välitettäessä paikallinen muuttuja, jota ei enää tarvita, sink-funktiolle
std::move-funktion toteutus
Se on vain naamioitu static_cast:
template <typename T>
typename std::remove_reference<T>::type&& move(T&& t) noexcept {
return static_cast<typename std::remove_reference<T>::type&&>(t);
}std::forward: säilytä arvokategoria
Forwarding reference -viittausta (T&&) käyttävässä mallissa std::forward<T>(x) muuntaa x:n takaisin alkuperäiseen arvokategoriaansa (lvalue- tai rvalue-arvoksi). Tätä käytetään täydelliseen välitykseen.
template <typename T>
void wrapper(T&& arg) {
target(std::forward<T>(arg)); // forwards as lvalue or rvalue depending on T
}Miksi välitystä tarvitaan
Mallin sisällä parametrilla on nimi — joten se on lvalue, vaikka kutsuja välitti rvalue-arvon. std::forward palauttaa alkuperäisen arvokategorian.
Ilman std::forward-funktiota
Ilman forward-funktiota jokainen argumentti välitettäisiin kääreen sisällä lvalue-arvona, mikä estäisi kutsujan haluaman siirtosemantiikan.
template <typename T>
void wrapper(T&& arg) {
target(arg); // always lvalue — wrong
}Määritä forward-funktion malliparametri aina
std::forward<T> vaatii eksplisiittisen malliparametrin. Ilman sitä toiminta olisi virheellistä.
Esimerkki täydellisestä välityksestä
Rakentajan argumentit välittävä tehdasfunktio säilyttää lvalue- ja rvalue-arvojen erot tehokkuuden vuoksi.
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}Siirtäkää kerran
Kustakin oliosta tulisi siirtää resurssit enintään kerran. Siirron jälkeen olio on kelvollisessa mutta määrittelemättömässä tilassa — yleensä se määritetään uudelleen tai tuhotaan. Siirretyn olion käyttäminen ilman sitä edeltävää uudelleenmäärittämistä voi aiheuttaa vaikeasti havaittavia virheitä.
Nyrkkisäännöt
Nopea ajatusmalli:
- Teillä on konkreettinen tyyppi ja haluatte siirtää sen →
std::move - Teillä on malliparametri ja haluatte säilyttää arvokategorian →
std::forward<T>
Pikatarkistus
Miten välitätte arg-parametrin mallifunktion sisällä, kun parametrina on T&& arg, ja säilytätte samalla sen lvalue- tai rvalue-arvokategorian?
Kertaus
std::move muuntaa ehdoitta rvalue-arvoksi — käyttäkää sitä konkreettisiin olioihin, joiden resurssit haluatte varastaa. std::forward<T> säilyttää arvokategorian yleisissä malleissa — käyttäkää sitä täydelliseen välitykseen.
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 ”std::move ja std::forward” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa C++ Academy-oppimispolun 3 oppituntia, myös oppitunnin “std::move ja std::forward”. 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 ”std::move ja std::forward”?
Muunna lvaluet rvalueiksi std::movella ja säilytä arvokategoria std::forwardilla. 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 3/4.
Kuinka kauan ”std::move ja std::forward”-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
- Lvalue ja rvalue: ero
- Rvalue-viitteet ja &&-syntaksi
- std::move ja std::forward
- Siirtokonstruktorit ja siirtosijoitus