std::move and std::forward
Cast lvalues to rvalues with std::move and preserve value category with std::forward.
std::move and std::forward is a free C++ Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C++ Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Two Cousins, Different Jobs
std::move and std::forward are both compile-time casts. They look similar but solve different problems.
std::move: Always Cast to Rvalue
std::move(x) unconditionally casts x to an rvalue reference. The receiving function can then steal its resources.
std::string s = "Hello";
std::string t = std::move(s); // move-constructs t from s
// s is now in a valid-but-unspecified stateWhen to Use move
Use std::move in:
- Move constructors and move assignment operators
- Returning a local variable when you want to force a move (rarely needed — RVO usually applies)
- Passing a local you no longer need into a sink function
std::move Implementation
It is just a static_cast in disguise:
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: Preserve Category
In a template that uses a forwarding reference (T&&), std::forward<T>(x) casts x back to its original category (lvalue or rvalue). Used for perfect forwarding.
template <typename T>
void wrapper(T&& arg) {
target(std::forward<T>(arg)); // forwards as lvalue or rvalue depending on T
}Why Forwarding Is Needed
Inside the template, the parameter has a name — making it an lvalue, even if the caller passed an rvalue. std::forward recovers the original category.
Without std::forward
Without forward, every argument would be passed as an lvalue inside the wrapper, defeating any move semantics the caller wanted.
template <typename T>
void wrapper(T&& arg) {
target(arg); // always lvalue — wrong
}Always Specify Template Parameter to forward
std::forward<T> requires the explicit template argument. Without it, the behavior would be incorrect.
Perfect Forwarding Example
A factory function that forwards constructor arguments preserves rvalue/lvalue distinctions for efficiency.
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}Move Once
Each object should be moved from at most once. After moving, it is in a valid-but-unspecified state — usually you reassign or destroy it. Using a moved-from object without reassigning first risks subtle bugs.
Rules of Thumb
Quick mental model:
- Have a concrete type and want to move it →
std::move - Have a template parameter and want to preserve category →
std::forward<T>
Quick Check
Inside a template function with parameter T&& arg, how do you forward arg while preserving its lvalue/rvalue category?
Recap
std::move unconditionally casts to rvalue — use on concrete objects you want to steal from. std::forward<T> preserves the value category inside generic templates — use for perfect forwarding.
Frequently asked questions
Is the “std::move and std::forward” lesson free?
Yes — the full text of “std::move and std::forward” is free to read here on the web, and the C++ Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C++ Academy course, upgrade to CoddyKit PRO.
What will I learn in “std::move and std::forward”?
Cast lvalues to rvalues with std::move and preserve value category with std::forward. You practise C++ Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C++ Academy?
No prior experience is required. C++ Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “std::move and std::forward” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C++ Academy lesson?
Yes. Every C++ Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Lvalue vs Rvalue The Distinction
- Rvalue References and the && Syntax
- std::move and std::forward
- Move Constructors and Move Assignment