# Ultimate functor class which can read/write to l-values/r-values

The aim is to provide a generic functor class which makes references able to bind to r-values. The trick is to trick the compiler into thinking that the r-value is an l-value by using a forwarding references. Here is the code:

#include <type_traits>
template <typename Functor>
struct Function {
Functor func;
template <typename ...Args>
inline auto operator() (Args&&... args) {
//I tried to provide a suitable error message if args were not valid parameters, but I can't get it to work...
//static_assert(std::is_invocable_v<Functor, Args...>);
return func(args...);
}
};


Example use case:

# include <iostream>
# include <vector>
int main () {
// Define function
auto push_back = Function([] (std::vector<int>& vec, int num) {vec.push_back(num); return vec;});
auto x = std::vector{1 , 2 ,3 , 4};
// Works on l-values
push_back(x, 5);
std::cout << x[4] << '\n'; // 5
// Works on r-values
auto y = push_back(std::vector{1 ,2 , 3 , 4 , 5}, 6);
std::cout << y[5] << '\n'; // 6
return 0;
}


And finally, one can do this if you want to use old-style c functions:

template <typename R, typename ...Args>
inline auto CFunc(R (*iFunc) (Args...)) {
return Function<R (*) (Args...)>(iFunc);
}


Is this robust code? Are there edge cases I need to be aware about with which my functor class does not work? Also, how could I provide more suitable error messages, eg when typename Functor is not a functor, or when args... are not suitable parameters?

Assuming C++20, we can constrain the template (similar to your attempt at static_assert). The key is that Args... can contain rvalue-references, but we need to convert those to lvalue types, because that's what we present to the function:
#include <concepts>

    template<typename... Args>