[Bug libstdc++/80564] bind on SFINAE unfriendly generic lambda

2017-05-04 Thread colu...@gmx-topmail.de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80564

--- Comment #7 from Robert Haberlach  ---
Oh, damn. "Submit only my new comment" does not what I thought it does. :-)

[Bug libstdc++/80564] bind on SFINAE unfriendly generic lambda

2017-05-04 Thread colu...@gmx-topmail.de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80564

--- Comment #6 from Robert Haberlach  ---
(In reply to TC from comment #4)
> (In reply to Eric Fiselier from comment #3)
> > Here is an example of why `_Bind::operator()(...) const` must be considered
> > during overload resolution even if the call wrapper itself is not const.
> > 
> > --
> > #include 
> > 
> > struct Func {
> >   template 
> >   void operator()(Args&&...) = delete;
> > 
> >   template 
> >   void operator()(Args&&...) const {}
> > };
> > 
> > int main() {
> > Func f;
> > std::bind(f)();
> > }
> > -
> 
> Interesting, libstdc++ rejects this as an attempt to call a deleted
> function. That seems more correct than libc++'s approach which calls the
> const overload.

See also the discussion on Phabricator: https://reviews.llvm.org/D32824

I agree. AFAICS [func.bind.bind] is clear on this: the type of the Func
object used to call the member operator() is non-const.

[Bug libstdc++/80564] bind on SFINAE unfriendly generic lambda

2017-05-04 Thread r.hl at gmx dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80564

--- Comment #5 from r.hl at gmx dot net ---
See also the discussion on Phabricator: https://reviews.llvm.org/D32824

I agree; AFAICS [func.bind.bind] is clear on this: the type of the Func
object used to call the member operator() is non-const.

On 5/4/2017 9:09 PM, rs2740 at gmail dot com wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80564
>
> TC  changed:
>
>What|Removed |Added
> 
>  CC||rs2740 at gmail dot com
>
> --- Comment #4 from TC  ---
> (In reply to Eric Fiselier from comment #3)
>> Here is an example of why `_Bind::operator()(...) const` must be considered
>> during overload resolution even if the call wrapper itself is not const.
>>
>> --
>> #include 
>>
>> struct Func {
>>   template 
>>   void operator()(Args&&...) = delete;
>>
>>   template 
>>   void operator()(Args&&...) const {}
>> };
>>
>> int main() {
>> Func f;
>> std::bind(f)();
>> }
>> -
> Interesting, libstdc++ rejects this as an attempt to call a deleted function.
> That seems more correct than libc++'s approach which calls the const overload.
>

[Bug libstdc++/80564] bind on SFINAE unfriendly generic lambda

2017-05-04 Thread rs2740 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80564

TC  changed:

   What|Removed |Added

 CC||rs2740 at gmail dot com

--- Comment #4 from TC  ---
(In reply to Eric Fiselier from comment #3)
> Here is an example of why `_Bind::operator()(...) const` must be considered
> during overload resolution even if the call wrapper itself is not const.
> 
> --
> #include 
> 
> struct Func {
>   template 
>   void operator()(Args&&...) = delete;
> 
>   template 
>   void operator()(Args&&...) const {}
> };
> 
> int main() {
> Func f;
> std::bind(f)();
> }
> -

Interesting, libstdc++ rejects this as an attempt to call a deleted function.
That seems more correct than libc++'s approach which calls the const overload.

[Bug libstdc++/80564] bind on SFINAE unfriendly generic lambda

2017-05-03 Thread eric at efcs dot ca
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80564

--- Comment #3 from Eric Fiselier  ---
Here is an example of why `_Bind::operator()(...) const` must be considered
during overload resolution even if the call wrapper itself is not const.

--
#include 

struct Func {
  template 
  void operator()(Args&&...) = delete;

  template 
  void operator()(Args&&...) const {}
};

int main() {
Func f;
std::bind(f)();
}
-

[Bug libstdc++/80564] bind on SFINAE unfriendly generic lambda

2017-05-03 Thread eric at efcs dot ca
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80564

--- Comment #2 from Eric Fiselier  ---
Note that explicitly providing a return type for the lambda avoids this compile
error. Example:

---
#include 

int main() {
int i;
std::bind([] (auto& x) -> void {x = 1;}, i)(); // OK!
}

---

[Bug libstdc++/80564] bind on SFINAE unfriendly generic lambda

2017-05-03 Thread eric at efcs dot ca
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80564

Eric Fiselier  changed:

   What|Removed |Added

 CC||eric at efcs dot ca

--- Comment #1 from Eric Fiselier  ---
Note that the instantiation is not spurious, but instead required by the core
language. All overloads of _Bind::operator() are considered during the call to
the forwarding call wrapper.

While considering the const qualified overload the compiler is forced to
instantiate the lambda to deduce the return type. This causes a error in a
non-immediate context which causes the compile error.