std::forward and operator() - c++

I've been looking into writing a static_if for my C++ project, and I stumbled across the following piece of code:
#include <iostream>
using namespace std;
namespace static_if_detail {
struct identity {
template<typename T>
T operator()(T&& x) const {
return std::forward<T>(x);
}
};
template<bool Cond>
struct statement {
template<typename F>
void then(const F& f){
f(identity());
}
template<typename F>
void else_(const F&){}
};
template<>
struct statement<false> {
template<typename F>
void then(const F&){}
template<typename F>
void else_(const F& f){
f(identity());
}
};
} //end of namespace static_if_detail
template<bool Cond, typename F>
static_if_detail::statement<Cond> static_if(F const& f){
static_if_detail::statement<Cond> if_;
if_.then(f);
return if_;
}
template<typename T>
void decrement_kindof(T& value){
static_if<std::is_same<std::string, T>::value>([&](auto f){
f(value).pop_back();
}).else_([&](auto f){
--f(value);
});
}
int main() {
// your code goes here
std::string myString{"Hello world"};
decrement_kindof(myString);
std::cout << myString << std::endl;
return 0;
}
It all makes sense to me, except for one thing: the overloaded operator() in struct identity. It takes in a rhs of type T called x, cool and all. But when identity is called, nothing is actually passed into identity.
template<typename F>
void then(const F& f){
f(identity());
}
Above, f calls identity, but passes nothing onto identity. Yet identity returns the forwarded arguments (in my case, an std::string), and pops the backmost character of the string.
How is identity returning a forwarded argument, when itself has no arguments passed into it to forward?

f doesn't call identity - f is called with an instance of identity. Walking through the two cases here:
static_if<std::is_same<std::string, T>::value>([&](auto f){
f(value).pop_back();
}).else_([&](auto f){
--f(value);
});
If T is std::string, then we instantiate a statement<true> whose then() invokes the passed-in function with an instance of identity. The argument to the first lambda, f, will be of type identity - so f(value) is really just value and we do value.pop_back().
If T is not std::string, then we instantiate a statement<false> whose then() does nothing, and whose else_() invokes the lambda with an instance of identity. Again f(value) is just value and we do --value.
This is a really confusing implementation of static_if, since f in the lambda is always an identity. It's necessary to do because we can't use value directly (can't write value.pop_back() since there's no dependent name there so the compiler will happily determine that it's ill-formed for integers), so we're just wrapping all uses of value in a dependent function object to delay that instantiation (f(value) is dependent on f, so can't be instantiated until f is provided - which won't happen if the function isn't called).
It would be better to implement it so that you actually pass in the arguments to the lambda.

template<typename F>
void then(const F& f){
f(identity());
}
Is more readable as
template<typename F>
void then(const F& f){
f(identity{});
}
they are construcing an identity object, not calling one.
The trick here is that the non-dependent parts of a template function must be valid even if the function is never instantiated.
So saying value.pop_back() is never valid within the lambda when value is an integer.
By passing identity{} to exactly one of the then or else cases, we can avoid this problem.
The statement f(value) produces a dependent type. So it need only be valid when the template operator() of the lambda is actually instantiated (there must also be some possibke f that makes it valid, but that is a corner case).
As we only instantiate the path the condition tells us to, the f(value) can be used almost any way we want, so long as it is valid in the taken branch.
I would have called f a better name, like safe or guard or var or magic rather than f. The use of two fs different contexts in the terse code adds to the confusion.

Let us take the case, where your Cond is true in the static_if, hence, the primary template class will be used...
template<bool Cond>
struct statement {
template<typename F>
void then(const F& f){
f(identity());
}
template<typename F>
void else_(const F&){}
};
Recall, that your calling function is:
static_if<std::is_same<std::string, T>::value>
(
[&](auto f){ //This is the lamda passed, it's a generic lambda
f(value).pop_back();
}
).else_(
[&](auto f){
--f(value);
}
);
In the applying function below, F is a type of that generic lambda (meaning, you can call f with any type)
template<typename F>
void then(const F& f){
f(identity());
}
identity() creates an object of type identity which is then passed as an argument, to call your generic lambda.
[&](auto f){ //This is the lamda passed, it's a generic lambda
f(value).pop_back();
}
but recall, f is an object of type identity and has a templated call () operator, which basically returns the object passed to it.
So, we go like this:
void decrement_kindof(std::string& value){
static_if<std::is_same<std::string, std::string>::value>([&](auto f){
f(value).pop_back();
}).else_([&](auto f){
--f(value);
});
});
Reduced to:
void decrement_kindof(std::string& value){
static_if<true>([&](auto f){
f(value).pop_back();
}).else_([&](auto f){
--f(value);
});
});
Reduced to:
void decrement_kindof(std::string& value){
static_if<true>(
[&](identity ident){
auto&& x = ident(value); //x is std::string()
x.pop_back();
} (identity()) //<-- the lambda is called
).else_(
[&](auto f){ //This is not evaluated, because it's not called by the primary template of `statement`
--f(value);
}
);
});

Related

C++ template function pointer type deduction

I have the following code
using my_map_t = std::map<int, Object<double>>;
using my_map_iterator_t = my_map_t::iterator;
template <typename FWD, typename Func>
void inner(my_map_t& map, int key, FWD&& obj, Func emplacer) {
emplacer(map, key, std::forward<FWD>(obj));
}
my_map_t map;
template <typename FWD>
void outer(my_map_t& map, int key, FWD&& obj)
{
auto lambda = [](my_map_t& m, int k, FWD&& o) {
m.emplace(k, std::forward<FWD>(o));
};
inner(map, key, std::forward<FWD>(obj), lambda);
}
which compiles painlessly. So this means that he deduce automatically the template argument of inner function.
However, if I introduce a function pointer I need to specify the function pointer template argument, otherwise the compiler complaints
using my_map_t = std::map<int, Object<double>>;
using my_map_iterator_t = my_map_t::iterator;
template <typename FWD, typename Func>
void inner(my_map_t& map, int key, FWD&& obj, Func emplacer) {
emplacer(map, key, std::forward<FWD>(obj));
}
template <typename FWD, typename Func>
void(*fp)(my_map_t&, int, FWD&&, Func) = &inner;
my_map_t map;
template <typename FWD>
void outer(my_map_t& map, int key, FWD&& obj)
{
auto lambda = [](my_map_t& m, int k, FWD&& o) {
m.emplace(k, std::forward<FWD>(o));
};
(*fp<FWD, decltype(lambda)>)(map, key, std::forward<FWD>(obj), lambda);
}
Why in the case of function pointer the argument deduction is not working any more?
Did I make some mistake? Is there a way to achieve a better syntax?
NOTE ADDED
I need to use function pointer because I have some function with the same signature of inner. Let us call them inner1, inner2 and inner3. They are called by some outer function
void outer(...) {
if(...) {
inner1(...)
} else if (...) {
inner2(...)
} else {
inner3(...)
}
some_long_task(...)
}
Now in my case the outer function is called cyclically. The checks in the ifs can be time consuming and they are independent of the argument of outer function. I was thinking while the some_long_task is being executed, to set up a function pointer to the right function inner1, inner2 or inner3 exploiting some cpu parallelism, so that, the the new cycle begin, I do not have to waste time doing the if check.
template <typename FWD, typename Func>
void(*fp)(my_map_t&, int, FWD&&, Func) = &inner;
is not a normal function pointer. It is what's called a variable template. When you have a variable template, in order to refer to a specific instantiation, you must specify the template parameters. To demonstratre that, consider
template <typename T>
constexpr T pi = T(3.1415926535897932385L);
You can't just do cout << pi because we don't know which pi to use. The same occurs with
(*fp<FWD, decltype(lambda)>)(map, key, std::forward<FWD>(obj), lambda);
Here fp needs the <FWD, decltype(lambda)> so the compiler can know which specific fp instance to refer to. It has to do this even before it evaluates the function call because it needs to check the parameters against the function.
What we would need to not have to specify the parameter is a future like CTAD but would work for function pointer variable temapltes.

Forward a function into a lambda-expression in c++11

For a Packaged_Task implementation in C++11
i want to achieve what i've expressed in C++14 Code below. In other words i want to forward into a lambda expression.
template<class F>
Packaged_Task(F&& f) {
Promise<R> p;
_future = p.get_future();
auto f_holder = [f = std::forward<F>(f)]() mutable { return std::move(f); };
///...
I'm aware of workarounds for moving into a lambda (but unfortenately this workarounds need a default constructible Object, in my case the object is most often a lambda expression without default-constructor)
How about creating a wrapper struct which does a move during copy construction:(. (I know that's bad, makes me remember of auto_ptr)
template <typename F>
struct Wrapped {
using Ftype = typename std::remove_reference<F>::type;
Wrapped(Ftype&& f): f_(std::move(f)) {}
Wrapped(const Wrapped& o): f_(std::move(o.f_)) {}
mutable Ftype f_;
};
template<class F>
Packaged_Task(F&& f) {
Promise<R> p;
_future = p.get_future();
Wrapped<std::remove_reference<decltype(f)>::type> wrap(std::forward<F>(f));
auto f_holder = [wrap]() mutable { return std::move(wrap.f_); };
This is just a rough idea. Not compiled or tested.
NOTE: I have seen this technique before, do not remember whether it was on SO itself or on some blog.
First, let's boil down the question to its core: the function object is somewhat of a distraction. Essentially, you want to be able to create a lambda with a capture holding a move-only object. In C++11 that isn't directly supported which gave raise to the C++14 approach of allowing specification of how the capture is build.
For C++11 it is necessary to use a copy. Since the underlying type doesn't support copying, it become necessary to actually move the object instead of copying it. Doing so can be achieved by a suitable wrapper defining a copy constructor not really copying but rather moving. Here is an example showing that:
#include <utility>
struct foo {
foo(int) {}
foo(foo&&) = default;
foo(foo const&) = delete;
};
template <typename T>
class move_copy
{
T object;
public:
move_copy(T&& object): object(std::move(object)) {}
move_copy(move_copy& other): object(std::move(other.object)) {}
T extract() { return std::forward<T>(this->object); }
};
template <typename T>
void package(T&& object)
{
move_copy<T> mc(std::forward<T>(object));
foo g = [mc]() mutable { return mc.extract(); }();
}
int main()
{
foo f(0);
package(std::move(f));
}
The move_copy<T> wrapper actually just captures the argument the way it is passed: if an lvalue is being passed in, an lvalue is captured. To properly get hold of the contained object, the extract() member std::forward<T>()s the object: the function can be called only once safely as an object is potentially moved from there.
Breaking copy semantics by making it a move is a bad idea. If it was the only option, go for it, but it is not.
Instead, we can pass the moved value in as an argument to the lambda, and move it into the wrapping code.
curry_apply takes some value and a function object, and returns that function object with the value bound to the first argument.
template<class T, class F>
struct curry_apply_t {
T t;
F f;
template<class...Args>
auto operator()(Args&&...args)
-> typename std::result_of_t<F&(T&, Args...)>::type
{
return f(t, std::forward<Args>(args)...);
}
};
template<class T, class F>
curry_apply_t<typename std::decay<T>::type, typename std::decay<F>::type>
curry_apply( T&& t, F&& f ) {
return {std::forward<T>(t), std::forward<F>(f)};
}
Use:
template<class F>
Packaged_Task(F&& f) {
Promise<R> p;
_future = p.get_future();
auto f_holder = curry_apply(
std::move(_future),
[](Future<R>& f) mutable { return std::move(f); };
);
basically we store the moved-in data outside of the lambda in a manually written function object. We then pass it in as an lvalue argument at the front of the lambda's argument list.
Here is a more complex version of the same solution.

bind binded function as argument

I have a class foo with a method bar which takes something callable (function-pointer/ functor). this callable something should be passed to another method doit as an binded element with a third method bar_cb method.
#include <functional>
#include <iostream>
class foo {
public:
template<typename T>
void bar(T&& t) {
std::cout << "bar\n";
doit(std::bind(&foo::template bar_cb<T>, this, std::forward<T>(t)));
}
template<typename T>
void doit(T&& t) {
std::cout << "doit\n";
t();
}
template<typename T>
void bar_cb(T&& t) {
std::cout << "bar_cb\n";
t();
}
};
void lala() {
std::cout << "lala\n";
}
class functor {
public:
void operator()() {
std::cout << "functor::operator()\n";
}
};
int main() {
foo f;
functor fn;
f.bar(fn);
f.bar(std::bind(lala)); // error
return 0;
}
This works fine for functors but not for binded functions as argument for foo::bar (lala in my example). Is it possible to pass an unknowable type to a method and bind it in this method as an argument to another (and if so how)?
I know I could wrap a functor (std::function for example) around the function but since I can call an unknowable type I think there is a way to also bind it (I think I'm just missing something simple).
Here a link to an example.
The primary problem is that your bar_cb(T&&) doesn't deduce the template argument because the template argument is actually specified when using &foo::template bar_cb<X> with some template argument X. The bind() expression will, however, copy the bound function, i.e., it may or may not have the type which would be deduced. Also, std::bind() will not pass bind()-expression through but will rather call them!
The easiest work around is to not use std::bind() to bind the function but rather to use a lambda function:
template<typename T>
void bar(T&& t) {
std::cout << "bar\n";
doit([=](){ this->bar_cb(t); });
}
Doing so let's the compiler deduce the correction argument type for bar_cb() (with C++14 you may want to use the capture [this,t = std::forward<T>(t)] although your bar_cb() still won't see an rvalue).
To pass an already bind()-expression through another bind()-expression, without having bind() consider the inner bind()-expression a bind()-expression you need to make it look as if it is not a bind()-expression. You could do so with a thin function wrapper:
template <typename Fun>
class unbinder {
Fun fun;
public:
template <typename F>
unbinder(F&& fun): fun(std::forward<F>(fun)) {}
template <typename... Args>
auto operator()(Args&&... args) const
-> decltype(fun(std::forward<Args>(args)...)) {
return fun(std::forward<Args>(args)...);
}
};
template <typename Fun>
auto unbind(Fun&& fun)
-> unbinder<Fun> {
return unbinder<Fun>(std::forward<Fun>(fun));
}
Since the function stored in the bind() expression will be passed by lvalue, you'll need a different declaration for your bar_cb(), however:
template<typename T>
void bar_cb(T& t) {
...
}
With that, you can register the bind()-expression using
f.bar(unbind(std::bind(lala)));
If you want to use f.bar(std::bind(lala)) you'll need a conditional definition of bar(): if it receives a bind()-expression it needs to automatically hide the fact that it is a bind()-expression by applying unbind() or something similar:
template<typename T>
typename std::enable_if<!std::is_bind_expression<typename std::decay<T>::type>::value>::type
bar(T&& t) {
std::cout << "bar (non-bind)\n";
doit(std::bind(&foo::template bar_cb<T>, this, std::forward<T>(t)));
}
template<typename T>
typename std::enable_if<std::is_bind_expression<typename std::decay<T>::type>::value>::type
bar(T&& t) {
std::cout << "bar (bind)\n";
doit(std::bind(&foo::template bar_cb<unbinder<T>>, this, unbind(std::forward<T>(t))));
}

Const and non-const functors

This seems like something that ought to be frequently asked and answered, but my search-fu has failed me.
I'm writing a function which I want to accept a generic callable object of some kind (including bare function, hand-rolled functor object, bind, or std::function) and then invoke it within the depths of an algorithm (ie. a lambda).
The function is currently declared like this:
template<typename T, typename F>
size_t do_something(const T& a, const F& f)
{
T internal_value(a);
// do some complicated things
// loop {
// loop {
f(static_cast<const T&>(internal_value), other_stuff);
// do some more things
// }
// }
return 42;
}
I'm accepting the functor by reference because I want to guarantee that it does not get copied on entry to the function, and thus the same instance of the object is actually called. And it's a const reference because this is the only way to accept temporary objects (which are common when using hand-rolled functors or bind).
But this requires that the functor implement operator() as const. I don't want to require that; I want it to be able to accept both.
I know I can declare two copies of this method, one that accepts it as const and one as non-const, in order to cover both cases. But I don't want to do that as the comments are hiding quite a lot of code that I don't want to duplicate (including some loop constructs, so I can't extract them to a secondary method without just moving the problem).
I also know I could probably cheat and const_cast the functor to non-const before I invoke it, but this feels potentially dangerous (and in particular would invoke the wrong method if the functor intentionally implements both const and non-const call operators).
I've considered accepting the functor as a std::function/boost::function, but this feels like a heavy solution to what ought to be a simple problem. (Especially in the case where the functor is supposed to do nothing.)
Is there a "right" way to satisfy these requirements short of duplicating the algorithm?
[Note: I would prefer a solution that does not require C++11, although I am interested in C++11 answers too, as I'm using similar constructs in projects for both languages.]
Have you tried a forwarding layer, to force inference of the qualifier? Let the compiler do the algorithm duplication, through the normal template instantiation mechanism.
template<typename T, typename F>
size_t do_something_impl(const T& a, F& f)
{
T internal_value(a);
const T& c_iv = interval_value;
// do some complicated things
// loop {
// loop {
f(c_iv, other_stuff);
// do some more things
// }
// }
return 42;
}
template<typename T, typename F>
size_t do_something(const T& a, F& f)
{
return do_something_impl<T,F>(a, f);
}
template<typename T, typename F>
size_t do_something(const T& a, const F& f)
{
return do_something_impl<T,const F>(a, f);
}
Demo: http://ideone.com/owj6oB
The wrapper should be completely inlined and have no runtime cost at all, except for the fact that you might end up with more template instantiations (and therefore larger code size), though that will only happen when for types with no operator()() const where both const (or temporary) and non-const functors get passed.
Answer for new relaxed requirements.
In commentary on another answer the OP has clarified/changed the requirements to…
“I'm ok with requiring that if the functor is passed in as a temporary
then it must have an operator() const. I just don't want to limit it
to that, such that if a functor is not passed in as a temporary (and
also not a const non-temporary, of course) then it is allowed to have
a non-const operator(), and this will be called”
This is then not a problem at all: just provide an overload that accepts a temporary.
There are several ways of distinguishing the original basic implementation, e.g. in C++11 an extra default template argument, and in C++03 an extra defaulted ordinary function argument.
But the most clear is IMHO to just give it a different name and then provide an overloaded wrapper:
template<typename T, typename F>
size_t do_something_impl( T const& a, F& f)
{
T internal_value(a);
// do some complicated things
// loop {
// loop {
f(static_cast<const T&>(internal_value), other_stuff);
// do some more things
// }
// }
return 42;
}
template<typename T, typename F>
size_t do_something( T const& a, F const& f)
{ return do_something_impl( a, f ); }
template<typename T, typename F>
size_t do_something( T const& a, F& f)
{ return do_something_impl( a, f ); }
Note: there's no need to specify the do_something_impl instantiation explicitly, since it's inferred from the lvalue arguments.
The main feature of this approach is that it supports simpler calls, at the cost of not supporting a temporary as argument when it has non-const operator().
Original answer:
Your main goal is to avoid copying of the functor, and to accept a temporary as actual argument.
In C++11 you can just use an rvalue reference, &&
For C++03 the problem is a temporary functor instance as actual argument, where that functor has non-const operator().
One solution is to pass the burden to the client code programmer, e.g.
require the actual argument to be an lvalue, not a temporary, or
require explicit specification that the argument is a temporary, then take it as reference to const and use const_cast.
Example:
template<typename T, typename F>
size_t do_something( T const& a, F& f)
{
T internal_value(a);
// do some complicated things
// loop {
// loop {
f(static_cast<const T&>(internal_value), other_stuff);
// do some more things
// }
// }
return 42;
}
enum With_temp { with_temp };
template<typename T, typename F>
size_t do_something( T const& a, With_temp, F const& f )
{
return do_something( a, const_cast<F&>( f ) );
}
If it is desired to directly support temporaries of const type, to ease the client code programmer's life also for this rare case, then one solution is to just add an additional overload:
enum With_const_temp { with_const_temp };
template<typename T, typename F>
size_t do_something( T const& a, With_const_temp, F const& f )
{
return do_something( a, f );
}
Thanks to Steve Jessop and Ben Voigt for discussion about this case.
An alternative and much more general C++03 way is to provide the following two little functions:
template< class Type >
Type const& ref( Type const& v ) { return v; }
template< class Type >
Type& non_const_ref( Type const& v ) { return const_cast<T&>( v ); }
Then do_something, as given above in this answer, can be called like …
do_something( a, ref( MyFunctor() ) );
do_something( a, non_const_ref( MyFunctor() ) );
Why I didn't think of that immediately, in spite of having employed this solution for other things like string building: it's easy to create complexity, harder to simplify! :)

Function wrapper that works for all kinds of functors without casting

I'd like to create a function that takes a weak pointer and any kind of functor (lambda, std::function, whatever) and returns a new functor that only executes the original functor when the pointer was not removed in the meantime (so let's assume there is a WeakPointer type with such semantics). This should all work for any functor without having to specify explicitly the functor signature through template parameters or a cast.
EDIT:
Some commenters have pointed out that std::function - which I used in my approach - might not be needed at all and neither might the lambda (though in my original question I also forgot to mention that I need to capture the weak pointer parameter), so any alternative solution that solves the general problem is of course is also highly appreciated, maybe I didn't think enough outside the box and was to focused on using a lambda + std::function. In any case, here goes what I tried so far:
template<typename... ArgumentTypes>
inline std::function<void(ArgumentTypes...)> wrap(WeakPointer pWeakPointer, const std::function<void(ArgumentTypes...)>&& fun)
{
return [=] (ArgumentTypes... args)
{
if(pWeakPointer)
{
fun(args...);
}
};
}
This works well without having to explicitly specify the argument types if I pass an std::function, but fails if I pass a lambda expression. I guess this because the std::function constructor ambiguity as asked in this question. In any case, I tried the following helper to be able to capture any kind of function:
template<typename F, typename... ArgumentTypes>
inline function<void(ArgumentTypes...)> wrap(WeakPointer pWeakPointer, const F&& fun)
{
return wrap(pWeakPointer, std::function<void(ArgumentTypes...)>(fun));
}
This now works for lambdas that don't have parameters but fails for other ones, since it always instantiates ArgumentTypes... with an empty set.
I can think of two solution to the problem, but didn't manage to implement either of them:
Make sure that the correct std::function (or another Functor helper type) is created for a lambda, i.e. that a lambda with signature R(T1) results in a std::function(R(T1)) so that the ArgumentTypes... will be correctly deduced
Do not put the ArgumentTypes... as a template parameter instead have some other way (boost?) to get the argument pack from the lambda/functor, so I could do something like this:
-
template<typename F>
inline auto wrap(WeakPointer pWeakPointer, const F&& fun) -> std::function<void(arg_pack_from_functor(fun))>
{
return wrap(pWeakPointer, std::function<void(arg_pack_from_functor(fun))(fun));
}
You don't have to use a lambda.
#include <iostream>
#include <type_traits>
template <typename F>
struct Wrapper {
F f;
template <typename... T>
auto operator()(T&&... args) -> typename std::result_of<F(T...)>::type {
std::cout << "calling f with " << sizeof...(args) << " arguments.\n";
return f(std::forward<T>(args)...);
}
};
template <typename F>
Wrapper<F> wrap(F&& f) {
return {std::forward<F>(f)};
}
int main() {
auto f = wrap([](int x, int y) { return x + y; });
std::cout << f(2, 3) << std::endl;
return 0;
}
Assuming the weak pointer takes the place of the first argument, here's how I would do it with a generic lambda (with move captures) and if C++ would allow me to return such a lambda:
template<typename Functor, typename Arg, typename... Args>
auto wrap(Functor&& functor, Arg&& arg)
{
return [functor = std::forward<Functor>(functor)
, arg = std::forward<Arg>(arg)]<typename... Rest>(Rest&&... rest)
{
if(auto e = arg.lock()) {
return functor(*e, std::forward<Rest>(rest)...);
} else {
// Let's handwave this for the time being
}
};
}
It is possible to translate this hypothetical code into actual C++11 code if we manually 'unroll' the generic lambda into a polymorphic functor:
template<typename F, typename Pointer>
struct wrap_type {
F f;
Pointer pointer;
template<typename... Rest>
auto operator()(Rest&&... rest)
-> decltype( f(*pointer.lock(), std::forward<Rest>(rest)...) )
{
if(auto p = lock()) {
return f(*p, std::forward<Rest>(rest)...);
} else {
// Handle
}
}
};
template<typename F, typename Pointer>
wrap_type<typename std::decay<F>::type, typename std::decay<Pointer>::type>
wrap(F&& f, Pointer&& pointer)
{ return { std::forward<F>(f), std::forward<Pointer>(pointer) }; }
There are two straightforward options for handling the case where the pointer has expired: either propagate an exception, or return an out-of-band value. In the latter case the return type would become e.g. optional<decltype( f(*pointer.lock(), std::forward<Rest>(rest)...) )> and // Handle would become return {};.
Example code to see everything in action.
[ Exercise for the ambitious: improve the code so that it's possible to use auto g = wrap(f, w, 4); auto r = g();. Then, if it's not already the case, improve it further so that auto g = wrap(f, w1, 4, w5); is also possible and 'does the right thing'. ]