std::forward with concept (C++)

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