values.cpp)L-values and r-values revisited
struct DR-value reference is an l-value
Summary of value categories
i, s[i] (assuming i is int, and s is std::string)R-values have two sub-categories: prvalues and xvalues
2.0, s + s (where s is a string), string{"abc"}std::move(s)fwd-ref.cpp)template <typename T> void f1(T t) { t += 0.1; }
template <typename T> void f2(T& t) { t += 0.2; }
template <typename T> void f3(T&& t) { t += 0.3; }
T&& t parameter is called a forwarding reference if T is a type parameter of a function template
D d1 {1.0};
f3(d1); // lvalue arg: T = D&, so T&& is D&
f3(D(2.0)); // rvalue arg: T = D, so T&& is D&&
C++ collapses references as follows in templates and type aliases:
X& & collapses to X&
X& && collapses to X&
X&& & collapses to X&
X&& && collapses to X&&
template <typename T> void f4(T&& t) { D d{t}; d += 0.4; }
D d{t}; is always a copy construction.template <typename T> void f5(T&& t) { D d{std::forward<T>(t)}; d += 0.5; }
std::forward<T>() allows us to forward a forwarding reference without
losing its original value category; this is called perfect forwardingtemplate <typename T> void f6(T&& t) { D d{c2cpp::forward<T>(t)}; d += 0.6; }
A simplifed implementation of std::forward<T>():
template<typename T>
T&& forward(remove_reference_t<T>& t) noexcept {
return static_cast<T&&>(t);
}
variadic.cpp)Basic variadic template using template recursion
Function parameters as forwarding references to reduce copying
Fold expression