Introduction
- std::forward: Keeps the type of the reference. (lvalue, rvalue)
- concepts: Specify requirements for the template types.
Example
#include <concepts> #include <iostream> template <typename T> concept Callable = requires(T t) { { t() }; }; // The following line creates the same asm code // requires(T&& t) { { std::forward<T>(t)() }; }; struct Functor { void operator()() & { std::cout << "Called on lvalue\n"; } void operator()() && { std::cout << "Called on rvalue\n"; } }; template <Callable C> void execute(C&& c) { std::forward<C>(c)(); } // void execute(C&& c) { c(); } // Calls always "operator()() &" // void execute(C&& c) { std::move(c)(); } // Calls always "operator()() &&" int main() { Functor funct; execute(funct); execute(std::move(funct)); return 0; }
$ g++ main.cpp -std=c++20 $ ./a.out Called on lvalue Called on rvalue