It is possible to use the type of a lambda as a template argument, like
template<typename InArg, typename Function>
class selfCompose {
Function f;
public:
selfCompose(Function f): f(f) {}
auto operator() (InArg x) -> decltype(f(f(x))) {
return f(f(x)); }
};
int main() {
auto f = [](int x){return x*x;};
std::cout << selfCompose<int, decltype(f)>(f)(4) // yields (4²)² = 256
<< std::endl;
return 0;
}
However, this double use of f
is kind of redundant. We can omit passing the lambda's type as the template (casting it to a suitable std::function
(at loss of polymorphism – but C++ lambdas aren't parametrically polymorphic anyway)), however I have an application where I'd much prefer not having to pass its value to the constructor (because I'd like to use my class's initialisations themselves as a template parameter, where a particular constructor signature is expected). I'd like it to work like
template<class InArg, class Function>
class selfCompose {
Function f;
public:
selfCompose() {} // default constructor for f
auto operator() (InArg x) -> decltype(f(f(x))) {
return f(f(x)); }
};
int main() {
auto f = [](int x){return x*x;};
std::cout << selfCompose<int, decltype(f)>()(4) << std::endl;
return 0;
}
but this doesn't compile because lambdas have a deleted default constructor. Which is of course inevitable for capturing lambdas, but for simple ones like the one in my example this doesn't make much sense to me: they don't need to reference any local variables.
Is there some other way to get this functionality, or do I have to resort to defining the lambda old-fashionly as a named class?
struct myFun {
auto operator() (int x) -> int {return x*x;}
};
(of course, the lambda functions I'd like to use aren't quite as simple as x → x²
, so just selecting from a few standard function classes wouldn't be flexible enough)
You can follow the example of functions like make_pair
and make_shared
:
template<typename InArg, typename Function>
selfCompose<InArg, Function> make_selfCompose(Function f)
{
return selfCompose<InArg, decltype(f)>(f);
}
int main() {
auto f = [](int x){return x*x;};
std::cout << make_selfCompose<int>(f)(4)
<< std::endl;
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With