[thread] Ambiguity in variadic wait_for_all

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[thread] Ambiguity in variadic wait_for_all

Gavin Lambert
A colleague recently ran into an interesting issue when upgrading some
working code from Boost 1.55 to 1.60/1.63 (and from C++03 to C++11).

The exact details are unimportant, but it was trying to get the address
of boost::wait_for_all(Iterator, Iterator), for use in a Boost.Bind call.

In 1.55, this worked fine, although of course it had to supply template
parameters that proved the parameters were not futures (thus causing
enable_if<is_future_type<F1>> to fail, disabling the two-future-args
overload of the function.

In 1.60/1.63, the variadic method is encountered instead, which lacks
any enable_if condition and thus the ambiguity between the two remains
and the compiler errors out.  (When calling it directly, the variadic
one manages to get disabled as long as the iterator type lacks a wait()
method, but this doesn't apply when just getting the method address, as
it's not part of the signature.)

Should the variadic form also have enable_if?  Or is this considered
user error for trying to use Bind in a variadic-compatible compiler
instead of using a lambda?

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [thread] Ambiguity in variadic wait_for_all

Vicente Botet
Le 03/02/2017 à 02:38, Gavin Lambert a écrit :
A colleague recently ran into an interesting issue when upgrading some working code from Boost 1.55 to 1.60/1.63 (and from C++03 to C++11).

The exact details are unimportant, but it was trying to get the address of boost::wait_for_all(Iterator, Iterator), for use in a Boost.Bind call.

In 1.55, this worked fine, although of course it had to supply template parameters that proved the parameters were not futures (thus causing enable_if<is_future_type<F1>> to fail, disabling the two-future-args overload of the function.

In 1.60/1.63, the variadic method is encountered instead, which lacks any enable_if condition and thus the ambiguity between the two remains and the compiler errors out.  (When calling it directly, the variadic one manages to get disabled as long as the iterator type lacks a wait() method, but this doesn't apply when just getting the method address, as it's not part of the signature.)

Should the variadic form also have enable_if?  Or is this considered user error for trying to use Bind in a variadic-compatible compiler instead of using a lambda?
Hi,

I will suggest you to replace the call to bind by lambdas whenever you can.

You have made two changes IIUC, boost version and compiler version, so I don't know if this is a regression in boost 1.53  or a behavior that different between c++02 and C++11. I suspect that it  is the change to C++11.

Curiously I added enable if only for the function with two arguments, but not for the others.
    template<typename F1,typename F2>
    typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1,F2& f2)

When I added the C++11 version I surely forget to add the enable_if.

Please, could you try to add the enable_if to the variadic template and tell me if this would fix your issue?

    template<typename F1, typename... Fs>
    typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1, Fs&... fs)


Best,
Vicente

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [thread] Ambiguity in variadic wait_for_all

Gavin Lambert
On 8/02/2017 06:51, Vicente J. Botet Escriba wrote:
> You have made two changes IIUC, boost version and compiler version, so I
> don't know if this is a regression in boost 1.53  or a behavior that
> different between c++02 and C++11. I suspect that it  is the change to
> C++11.

Sorry, I gave a misleading impression there.  Both Boost versions were
tested with the same compiler (VS2015), so the issue was introduced by
the Boost upgrade only.

Explicitly disabling the variadic version by defining
BOOST_NO_CXX11_VARIADIC_TEMPLATES also avoids the issue, so I'm pretty
sure it's just the introduction of that which did it.

> Curiously I added enable if only for the function with two arguments,
> but not for the others.

That's correct -- only the two-argument form is ambiguous with the
iterator overload.

Although having said that, the iterator form takes a single template
parameter and the future form takes two template parameters, so the
compiler ought to be able to tell them apart (since the template
parameters were explicitly provided), unless it's trying to infer the
second parameter.

> Please, could you try to add the enable_if to the variadic template and
> tell me if this would fix your issue?
>
>     template<typename F1, typename... Fs>
>     *typename boost::enable_if<is_future_type<F1>,void>::type*
> wait_for_all(F1& f1, Fs&... fs)

Yes, making that change resolves the ambiguity and the original code
compiles again.


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [thread] Ambiguity in variadic wait_for_all

Boost - Users mailing list
Le 08/02/2017 à 00:09, Gavin Lambert a écrit :

> On 8/02/2017 06:51, Vicente J. Botet Escriba wrote:
>> You have made two changes IIUC, boost version and compiler version, so I
>> don't know if this is a regression in boost 1.53  or a behavior that
>> different between c++02 and C++11. I suspect that it  is the change to
>> C++11.
>
> Sorry, I gave a misleading impression there.  Both Boost versions were
> tested with the same compiler (VS2015), so the issue was introduced by
> the Boost upgrade only.
>
> Explicitly disabling the variadic version by defining
> BOOST_NO_CXX11_VARIADIC_TEMPLATES also avoids the issue, so I'm pretty
> sure it's just the introduction of that which did it.
>
>> Curiously I added enable if only for the function with two arguments,
>> but not for the others.
>
> That's correct -- only the two-argument form is ambiguous with the
> iterator overload.
>
> Although having said that, the iterator form takes a single template
> parameter and the future form takes two template parameters, so the
> compiler ought to be able to tell them apart (since the template
> parameters were explicitly provided), unless it's trying to infer the
> second parameter.
>
>> Please, could you try to add the enable_if to the variadic template and
>> tell me if this would fix your issue?
>>
>>     template<typename F1, typename... Fs>
>>     *typename boost::enable_if<is_future_type<F1>,void>::type*
>> wait_for_all(F1& f1, Fs&... fs)
>
> Yes, making that change resolves the ambiguity and the original code
> compiles again.
>
>
>
This will be fixed on next release.

Vicente


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users