I am trying to make a template class that expects a lambda as input, stores it, and also stores in a vector
some elements of type = return type
of the lambda. But I don't know how to get that type, even though when an instance is built the lambda is known with also its return type.
I'd like the class to be constructed without giving template parameters (like std::array a{1, 2, 3}
). I tried with decltype(F::operator(double x))
but it doesn't work.
#include <vector>
template<typename F>
struct Foo {
using value_t = decltype(F::operator(double x))// <--- here I need to get the return type of the
// call operator of F!
Foo(const F& f) : _f(f), _vals(10, value_t{}), _has_vals(10, false) {}
value_t operator()(int i) {
if (_has_vals[i])
return _vals[i];
else {
_has_vals[i] = true;
_vals[i] = _f(i);
}
}
F _f;
std::vector<value_t> _vals;
std::vector<bool> _has_vals;
};
#include <iostream>
int main() {
Foo foo([](double x){ return 42; }); // <--- here I know that the lambda returns an int!
std::cout << foo(3) << "\n";
return 0;
};
decltype
needs an actual call expression to get the return type, which you can't really reliably get from the type F
(because the type F
might not be default-constructible for example).
You must use std::declval
to "create" an instance of F
that you can then call.
Perhaps something like
using value_t = decltype(declval<F>()(0.0));