I'm writing a concept that checks if a type can be used in an expression that composes 2 functions:
template<typename T>
concept C = requires(T t) {
f(g(t));
};
i.e., I want to check if for a given object t of type T, I can call g(t) and then use the resulting value as an argument to f. e.g.,
auto g(int) -> float;
auto g(char) -> double;
void f(float);
void f(double) = delete;
static_assert(C<int>); // g(int) returns a float, so f(float) is called.
static_assert(not C<char>); // g(char) returns a double, but f(double) is deleted
This works just fine.
However, I want to split up the calls to f and g because 1) g may take additional arguments (that don't depend on T) resulting in a verbose call, and 2) I might want to use the return type/value of g multiple times inside the concept, so I don't want to repeat the call multiple times.
Naive attempts like the following
auto res = g(t);
f(res);
and
using ret_t = decltype(g(t));
f(ret_t{});
don't work inside concepts.
Is there some way to achieve the splitting up of f(g(t)) in a way that doesn't require writing g(t) inside the call to f?
A nested requirement can be an option:
And yes, requires requires is required here to make sure
f(s)is verified as well.