Rvalue references, std::move, std::forward. Core discipline: moved-from objects are valid-but-unspecified; move constructors should be noexcept or containers will copy.
Buffer(Buffer&& other) noexcept
: data_(std::exchange(other.data_, nullptr)),
size_(std::exchange(other.size_, 0)) {}
std::exchange lands (the one-liner for move constructors above), and init-captures move state into lambdas: [b = std::move(buf)].
Guaranteed copy elision: prvalues are initializations, not objects. Consequence: return x; is right and return std::move(x); on a local is a pessimization that blocks NRVO.
Widget make() {
Widget w;
w.configure();
return w;
}
P1825 widens implicit move: more returns of local variables and parameters (including rvalue-reference parameters) move automatically; another class of std::move calls becomes noise.
P2266 simplifies the implicit-move rules further, and auto(x) gives an explicit decay-copy in generic code. std::move_only_function finally stores move-only callables.
template <class R>
void take_snapshot(R&& range) {
process(auto(std::forward<R>(range)));
}
Trivial relocation (P2786): std::is_trivially_relocatable plus trivially_relocate let containers grow by memcpy instead of move+destroy pairs — move semantics meets its performance endgame.
static_assert(std::is_trivially_relocatable_v<SmallString>);
C++29direction · not adopted
Direction: library adoption of relocation (vector, inplace_vector optimizations) and the long-running destructive-move discussions continue.