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