Topic: Relax invokable requirements in std::function constructor


Author: Xavi <gratal@gmail.com>
Date: Thu, 28 Nov 2013 06:22:27 +0100
Raw View
int f();
std::function<void()> g(f);

The above code is illegal because int is not convertible to void. Most impl=
ementations of the standard library allow it but libc++ (correctly) rejects=
 it.=20

Using sfinae to check invokability helps select the correct overload when t=
here are several overloads of a function which take std::functions with dif=
ferent signatures. However, rejecting the above code is just silly, since f=
 is actually invokable in every way that a function with void() signature i=
s. Would it make sense to relax the restriction so that everything (maybe e=
verything destructible) is convertible to void in that context?

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 28 Nov 2013 13:30:25 +0800
Raw View
On 11/28/13 1:22 PM, Xavi wrote:
> int f();
> std::function<void()> g(f);
>
> The above code is illegal because int is not convertible to void. Most im=
plementations of the standard library allow it but libc++ (correctly) rejec=
ts it.
>
> Using sfinae to check invokability helps select the correct overload when=
 there are several overloads of a function which take std::functions with d=
ifferent signatures. However, rejecting the above code is just silly, since=
 f is actually invokable in every way that a function with void() signature=
 is. Would it make sense to relax the restriction so that everything (maybe=
 everything destructible) is convertible to void in that context?

A more conservative and general approach would be an adaptor object=20
which can store a functor and casts its return value.

std::function< void() > g( std::function_return_cast< void >( f ) );
std::function< long() > h( std::function_return_cast< long >( f ) );

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Xavi <gratal@gmail.com>
Date: Thu, 28 Nov 2013 08:16:50 +0100
Raw View

     xavi

> On 28 Nov 2013, at 06:30, David Krauss <potswa@gmail.com> wrote:
>=20
>> On 11/28/13 1:22 PM, Xavi wrote:
>> int f();
>> std::function<void()> g(f);
>>=20
>> The above code is illegal because int is not convertible to void. Most i=
mplementations of the standard library allow it but libc++ (correctly) reje=
cts it.
>>=20
>> Using sfinae to check invokability helps select the correct overload whe=
n there are several overloads of a function which take std::functions with =
different signatures. However, rejecting the above code is just silly, sinc=
e f is actually invokable in every way that a function with void() signatur=
e is. Would it make sense to relax the restriction so that everything (mayb=
e everything destructible) is convertible to void in that context?
>=20
> A more conservative and general approach would be an adaptor object which=
 can store a functor and casts its return value.
>=20
> std::function< void() > g( std::function_return_cast< void >( f ) );
> std::function< long() > h( std::function_return_cast< long >( f ) );

The thing is that the second cast is actually not necessary, because int is=
 convertible to long. So it's really counterintuitive that the first one is=
 necessary, especially when:

(void)f();

is actually a valid statement. So int is in some way convertible to void, o=
nly that void values can't be used almost anywhere.
>=20
> --=20
>=20
> --- You received this message because you are subscribed to the Google Gr=
oups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
 email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at http://groups.google.com/a/isocpp.org/group/std-propo=
sals/.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 28 Nov 2013 16:15:02 +0800
Raw View
On 11/28/13 3:16 PM, Xavi wrote:
> On 28 Nov 2013, at 06:30, David Krauss <potswa@gmail.com> wrote:
>> std::function< void() > g( std::function_return_cast< void >( f ) );
>> std::function< long() > h( std::function_return_cast< long >( f ) );
> The thing is that the second cast is actually not necessary, because int is convertible to long. So it's really counterintuitive that the first one is necessary, especially when:
>
> (void)f();
>
> is actually a valid statement. So int is in some way convertible to void, only that void values can't be used almost anywhere.

Int is explicitly convertible to void (3.9.1/1). I made a bad example by
showing a conversion that can be implicit. Base to derived pointer
conversion or int to scoped enum would be more illustrative.

Your proposal still sounds reasonable to me. I just wanted to point out
that this general kind of cast should also work within the semantics of
std::function.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.