C++ Academy · leksjon

std::move og std::forward

Konverter lvalues til rvalues med std::move, og bevar verdikategorien med std::forward.

Leksjon 3 av 413 trinn

std::move og std::forward er en gratis leksjon i C++ Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i C++ Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i C++ Academy inneholder totalt 4 leksjoner.

To søskenbarn med ulike oppgaver

std::move og std::forward er begge kompileringstids-caster. De ser like ut, men løser ulike problemer.

std::move: Cast alltid til rvalue

std::move(x) caster ubetinget x til en rvalue-referanse. Funksjonen som mottar verdien, kan deretter stjele ressursene dens.

std::string s = "Hello";
std::string t = std::move(s);   // move-constructs t from s
// s is now in a valid-but-unspecified state

Når move skal brukes

Bruk std::move i:

  • Flyttekonstruktører og flyttetilordningsoperatorer
  • Ved retur av en lokal variabel når De vil tvinge frem en flytting (sjelden nødvendig – RVO brukes vanligvis)
  • Når en lokal variabel som ikke lenger trengs, sendes til en sink-funksjon

Implementasjonen av std::move

Det er bare en forkledd 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: Bevare kategori

I en mal som bruker en videresendingsreferanse (T&&) caster std::forward<T>(x) x tilbake til den opprinnelige kategorien (lvalue eller rvalue). Dette brukes til perfekt videresending.

template <typename T>
void wrapper(T&& arg) {
    target(std::forward<T>(arg));  // forwards as lvalue or rvalue depending on T
}

Hvorfor videresending er nødvendig

Inne i malen har parameteren et navn og blir derfor en lvalue, selv om kalleren sendte en rvalue. std::forward gjenoppretter den opprinnelige kategorien.

Uten std::forward

Uten forward ville hvert argument blitt sendt som en lvalue inne i omslagsfunksjonen, og eventuell flyttesemantikk som kalleren ønsket, ville blitt satt ut av spill.

template <typename T>
void wrapper(T&& arg) {
    target(arg);    // always lvalue — wrong
}

Oppgi alltid malparameteren til forward

std::forward<T> krever det eksplisitte malargumentet. Uten det ville oppførselen vært feil.

Eksempel på perfekt videresending

En fabrikkfunksjon som videresender konstruktørargumenter, bevarer forskjellen mellom rvalue og lvalue for bedre effektivitet.

template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

Flytt én gang

Hvert objekt bør det maksimalt flyttes fra én gang. Etter en flytting er objektet i en gyldig, men uspesifisert tilstand – vanligvis tilordnes det en ny verdi eller ødelegges. Bruk av et objekt det er flyttet fra, uten først å tilordne det en ny verdi, kan føre til vanskelige feil.

Tommelfingerregler

En enkel mental modell:

  • Har De en konkret type og vil flytte den → std::move
  • Har De en malparameter og vil bevare kategorien → std::forward<T>

Kort sjekk

Inne i en malfunksjon med parameteren T&& arg, hvordan videresendes arg samtidig som lvalue/rvalue-kategorien bevares?

Oppsummering

std::move caster ubetinget til rvalue – bruk den på konkrete objekter De vil stjele ressurser fra. std::forward<T> bevarer verdikategorien inne i generiske maler – bruk den til perfekt videresending.

Gratis å komme i gang

Lær deg C++ med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
51
Leksjoner
203

Ofte stilte spørsmål

Er leksjonen «std::move og std::forward» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien C++ Academy, inkludert «std::move og std::forward», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i C++ Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «std::move og std::forward»?

Konverter lvalues til rvalues med std::move, og bevar verdikategorien med std::forward. Du øver på C++ Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med C++ Academy?

Ingen tidligere erfaring er nødvendig. C++ Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «std::move og std::forward»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne C++ Academy-leksjonen?

Ja. Alle C++ Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Lvalue kontra rvalue – forskjellen
  2. Rvalue-referanser og &&-syntaksen
  3. std::move og std::forward
  4. Flyttekonstruktører og flyttetilordning
← Tilbake til C++ Academy