Am Samstag, 16. September 2017 13:33:26 UTC+2 schrieb JiiPee:
>
> Thanks, something to try. But I think I really need to use this
> std::function here, because the real problem i have is to use it with
> templates, so I need to use std::function in my code.
That does not sound like an explanation for why you need std::function.
> In my real code i have something like:
>
> function f = foo<1>;
>
> and foo is a template function with default parameters.
>
> So i want to use f:
>
> f(1);
>
> f();
OK. But--as you know--it doesn't work. If f is of type
std::function<void(int)> it will have the following function call
operator:
void operator()(int) const;
and there is no default argument there, regardless of how you
initialize this function object. Now, you could write your own functor
like this:
struct myfunction {
std::function<void(int)> inner;
void operator()(int i=6) const { return inner(i); }
};
But this 6 here is a static property of myfunction. As such, you can't
change it at runtime and it doesn't depend on how yo initialize inner.
If you want to support changing default arguments you could do:
struct myfunction {
std::function<void(int)> inner;
int current_default;
void operator()(int i) const { return inner(i); }
void operator()() const { return inner(current_default); }
};
But C++ doesn't let you access default arguments. So, if you have
void foo(int = 6);
there is no way of extracting the default argument of foo. The only
way of making use of this default argument is by calling the function
directly by name without arguments. That's it. So, you would have to
replicate the default argument where you initialize myfunction:
myfunction mf = { &foo, 6 };
mf();
mf(42);
I don't see a way around it -- unless perhaps you *always* expect
there to be a default argument, in which case you *could* do this:
void foo(int = 6);
struct myfunction {
std::function<void()> inner1;
std::function<void(int)> inner2;
void operator()() const { return inner1(); }
void operator()(int i) const { return inner2(i); }
};
int main() {
myfunction mf = { []{foo();}, foo };
mf();
mf(42);
}
Here, foo is directly used within the lambda expression and without
an explicit argument. This makes the compiler lookup what foo is. It
finds the above declaration with the default argument and basically
turns the call foo() into foo(6) under the hood.
But ... you don't really wanna do that! Try to avoid it if possible.
Cheers!
sg