Discussion:
Defaulted parameters for std::function<>
(too old to reply)
'Johannes Schaub' via ISO C++ Standard - Discussion
2016-04-12 19:02:34 UTC
Permalink
Sometimes I have a template like so

template<typename F>
void iterate(F f) { f("bar"); f("bar", ReadWrite, true); ... }

As can be seen, "f" has some default arguments. Now I want to make
"iterate" virtual. Hence, it must become a non-template

virtual void iterate(std::function<void(std::string, ???)> f);

The problem here is, that std::function does not support defaulted
parameters. I want to observe the list about the reasons for this.
Would it not be cool to be able to say

virtual void iterate(std::function<void(std::string,
_defaulted<int, bool>)> f);

The semantics would be: If you assign a function object which accepts
fewer arguments, make the respective operators call that function
object with these number of arguments. If not supported, the
assignment will be ill-formed.

In other words, you can only assign suitable class-typed function
objects to above function parameter. But this is already very powerful
and would be very useful.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
David Krauss
2016-04-13 07:09:19 UTC
Permalink
Post by 'Johannes Schaub' via ISO C++ Standard - Discussion
Sometimes I have a template like so
template<typename F>
void iterate(F f) { f("bar"); f("bar", ReadWrite, true); ... }
As can be seen, "f" has some default arguments. Now I want to make
"iterate" virtual. Hence, it must become a non-template
virtual void iterate(std::function<void(std::string, ???)> f);
The problem here is, that std::function does not support defaulted
parameters.
This is covered by P0045R0. It will be revised soon, with a new P-number. See the prototype library <https://github.com/potswa/cxx_function> for a preview.
Post by 'Johannes Schaub' via ISO C++ Standard - Discussion
I want to observe the list about the reasons for this.
Would it not be cool to be able to say
virtual void iterate(std::function<void(std::string,
_defaulted<int, bool>)> f);
There’s no need for metaprogramming. The proposed feature simply type-erases each of a list of function call signatures, i.e. argument type lists. Those argument types may map to parameter types using conversion, template specialization, or default arguments.

So, you can have,

virtual void iterate(std::function< void(std::string), void(std::string, int, bool) > f);
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
'Johannes Schaub' via ISO C++ Standard - Discussion
2016-04-13 08:14:50 UTC
Permalink
Nice, this is definitely a proposal worth following. But it feels like
requiring to specify all signatures with the identical and growing prefix
typelist for having working default arguments is suboptimal.

I would prefer if there would be an alias template like
std::function_range_t<void(int), void(int, bool, char)> which would expand
into the correct intermediate function types. Perhaps there is an even
better notion for this which avoids repeating the prefix.
Post by David Krauss
On 2016–04–13, at 3:02 AM, 'Johannes Schaub' via ISO C++ Standard -
Sometimes I have a template like so
template<typename F>
void iterate(F f) { f("bar"); f("bar", ReadWrite, true); ... }
As can be seen, "f" has some default arguments. Now I want to make
"iterate" virtual. Hence, it must become a non-template
virtual void iterate(std::function<void(std::string, ???)> f);
The problem here is, that std::function does not support defaulted
parameters.
This is covered by P0045R0. It will be revised soon, with a new P-number.
See the prototype library for a preview.
Post by David Krauss
I want to observe the list about the reasons for this.
Would it not be cool to be able to say
virtual void iterate(std::function<void(std::string,
_defaulted<int, bool>)> f);
There’s no need for metaprogramming. The proposed feature simply
type-erases each of a list of function call signatures, i.e. argument type
lists. Those argument types may map to parameter types using conversion,
template specialization, or default arguments.
Post by David Krauss
So, you can have,
virtual void iterate(std::function< void(std::string),
void(std::string, int, bool) > f);
Post by David Krauss
--
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
David Krauss
2016-04-13 10:56:30 UTC
Permalink
Nice, this is definitely a proposal worth following. But it feels like requiring to specify all signatures with the identical and growing prefix typelist for having working default arguments is suboptimal.
I would prefer if there would be an alias template like std::function_range_t<void(int), void(int, bool, char)> which would expand into the correct intermediate function types. Perhaps there is an even better notion for this which avoids repeating the prefix.
Such a metafunction would be nice, but it sounds like a pure higher-level abstraction. Inside std::function, one way or another, each distinct parameter type list needs to map to a separate dispatcher. No special optimization is possible because there’s no way to extract the default values and store them inside the wrapper object. (And, attempting to do so would be a bit unsafe.)

Let me know if you come up with a nice interface that you’d like to share. It could be standardized at some point, though I don’t know if it would belong in the P0045R0 successor. I will add default arguments to the list of motivations though.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Richard Smith
2016-04-13 19:39:46 UTC
Permalink
On 2016–04–13, at 4:14 PM, 'Johannes Schaub' via ISO C++ Standard -
Nice, this is definitely a proposal worth following. But it feels like
requiring to specify all signatures with the identical and growing prefix
typelist for having working default arguments is suboptimal.
I would prefer if there would be an alias template like
std::function_range_t<void(int), void(int, bool, char)> which would expand
into the correct intermediate function types. Perhaps there is an even
better notion for this which avoids repeating the prefix.
Such a metafunction would be nice, but it sounds like a pure higher-level
abstraction. Inside std::function, one way or another, each distinct
parameter type list needs to map to a separate dispatcher. No special
optimization is possible because there’s no way to extract the default
values and store them inside the wrapper object. (And, attempting to do so
would be a bit unsafe.)
Let me know if you come up with a nice interface that you’d like to share.
It could be standardized at some point, though I don’t know if it would
belong in the P0045R0 successor. I will add default arguments to the list
of motivations though.
Just a thought, we can implement Johannes' syntax in terms of your proposal
fairly easily. That is, make std::function<void(std::string, defaulted<int,
bool>)> effectively be a synonym for std::function<void(std::string, int,
bool), void(std::string)>.

Sketch approach for exposition (obviously a real implementation would need
to write this in a way where the partial specialization is actually
deducible and apply it to every explicitly-specified type argument, not
just the first):

template<typename ...T> struct defaulted;

template<typename Signatures..., typename R, typename ...T, typename ...U>
struct function<Signatures..., R(T..., defaulted<U...>)>
: function<Signatures..., R(T..., U...), R(T...)> {
using function<Signatures..., R(T..., U...), R(T...)>::function;
};
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Thiago Macieira
2016-04-13 19:48:04 UTC
Permalink
Post by Richard Smith
Just a thought, we can implement Johannes' syntax in terms of your proposal
fairly easily. That is, make std::function<void(std::string, defaulted<int,
bool>)> effectively be a synonym for std::function<void(std::string, int,
bool), void(std::string)>.
Sketch approach for exposition (obviously a real implementation would need
to write this in a way where the partial specialization is actually
deducible and apply it to every explicitly-specified type argument, not
template<typename ...T> struct defaulted;
template<typename Signatures..., typename R, typename ...T, typename ...U>
struct function<Signatures..., R(T..., defaulted<U...>)>
: function<Signatures..., R(T..., U...), R(T...)> {
using function<Signatures..., R(T..., U...), R(T...)>::function;
};
How is std::function getting told what value to pass for the defaulted
arguments?
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
David Krauss
2016-04-14 02:08:04 UTC
Permalink
Post by Thiago Macieira
How is std::function getting told what value to pass for the defaulted
arguments?
It’s not. It would only be a shorthand for the multiple-signature usage I mentioned.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Giovanni Piero Deretta
2016-04-14 10:28:46 UTC
Permalink
Post by Richard Smith
On 2016–04–13, at 4:14 PM, 'Johannes Schaub' via ISO C++ Standard -
Nice, this is definitely a proposal worth following. But it feels like
requiring to specify all signatures with the identical and growing prefix
typelist for having working default arguments is suboptimal.
I would prefer if there would be an alias template like
std::function_range_t<void(int), void(int, bool, char)> which would expand
into the correct intermediate function types. Perhaps there is an even
better notion for this which avoids repeating the prefix.
Such a metafunction would be nice, but it sounds like a pure higher-level
abstraction. Inside std::function, one way or another, each distinct
parameter type list needs to map to a separate dispatcher. No special
optimization is possible because there’s no way to extract the default
values and store them inside the wrapper object. (And, attempting to do so
would be a bit unsafe.)
Let me know if you come up with a nice interface that you’d like to
share. It could be standardized at some point, though I don’t know if it
would belong in the P0045R0 successor. I will add default arguments to the
list of motivations though.
Just a thought, we can implement Johannes' syntax in terms of your
proposal fairly easily. That is, make std::function<void(std::string, defaulted<int,
bool>)> effectively be a synonym for std::function<void(std::string, int,
bool), void(std::string)>.
it should probably be an alias for function<void(string, int, bool),
void(string, int), void(string)>.

<bikeshed>
what about this sintax: function<void(string, int, bool), defaulted<2> >
</bikeshed>

in fact it probably isn't even worth adding direct support to function<>,
as it should be easy to write a metafunction to generate all signatures an
pass them to function<>.

-- gpd
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Richard Smith
2016-04-14 18:01:17 UTC
Permalink
Post by Giovanni Piero Deretta
Post by Richard Smith
On 2016–04–13, at 4:14 PM, 'Johannes Schaub' via ISO C++ Standard -
Nice, this is definitely a proposal worth following. But it feels like
requiring to specify all signatures with the identical and growing prefix
typelist for having working default arguments is suboptimal.
I would prefer if there would be an alias template like
std::function_range_t<void(int), void(int, bool, char)> which would expand
into the correct intermediate function types. Perhaps there is an even
better notion for this which avoids repeating the prefix.
Such a metafunction would be nice, but it sounds like a pure
higher-level abstraction. Inside std::function, one way or another,
each distinct parameter type list needs to map to a separate dispatcher. No
special optimization is possible because there’s no way to extract the
default values and store them inside the wrapper object. (And, attempting
to do so would be a bit unsafe.)
Let me know if you come up with a nice interface that you’d like to
share. It could be standardized at some point, though I don’t know if it
would belong in the P0045R0 successor. I will add default arguments to the
list of motivations though.
Just a thought, we can implement Johannes' syntax in terms of your
proposal fairly easily. That is, make std::function<void(std::string, defaulted<int,
bool>)> effectively be a synonym for std::function<void(std::string, int,
bool), void(std::string)>.
it should probably be an alias for function<void(string, int, bool),
void(string, int), void(string)>.
That could be written as std::function<void(std::string, defaulted<int>,
defaulted<bool>)>. There are cases where it doesn't make sense to pass only
one of two parameters with default arguments; it seemed reasonable to
support that here.
Post by Giovanni Piero Deretta
<bikeshed>
what about this sintax: function<void(string, int, bool), defaulted<2> >
</bikeshed>
in fact it probably isn't even worth adding direct support to function<>,
as it should be easy to write a metafunction to generate all signatures an
pass them to function<>.
If there were a clean syntax to use a metafunction to generate a *sequence*
of template arguments, I'd agree. Maybe that's the level at which to tackle
the problem :)
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Matthew Woehlke
2016-04-14 18:55:24 UTC
Permalink
Post by Richard Smith
If there were a clean syntax to use a metafunction to generate a *sequence*
of template arguments, I'd agree. Maybe that's the level at which to tackle
the problem :)
Ask Daveed about his parameter pack generators :-).
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Continue reading on narkive:
Loading...