std::forward with concept (C++)

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