See https://bugs.llvm.org/show_bug.cgi?id=32856. Basically, as this code was written before placeholder return types for functions were a
thing, the function call operators of bind apply decltype on the call expression to infer the return type. This can lead to hard errors when we pass
template functors. Another consequence of this is that the validity or invalidity of these call expressions influences overload resolution (via
SFINAE), hence the const version could be selected where the bind object was non-const, which is not the prescribed behaviour. This is fixed by
using placeholder return types.
Details
- Reviewers
howard.hinnant mclow.lists EricWF
Diff Detail
- Build Status
Buildable 6119 Build 6119: arc lint + arc unit
Event Timeline
This change regresses other code. By changing __bind_return<...>::type into decltype(auto) you prevent the member functions from SFINAE'ing. For example:
#include <functional> struct Func { template <class ...Args> void operator()(Args&&...) = delete; template <class ...Args> void operator()(Args&&...) const {} }; int main() { Func f; std::bind(f)(); // Broken after your change. }
This patch cannot introduce regressions but changing to using decltype(auto) does. I'm not sure the behavior you want is possible. The library is required to evaluate the validity of calling the specified functor in the signature of the call operator in order to correctly SFINAE.
I think this makes accepting the code in PR32856 impossible.
This is intended to fail (as I also mentioned in the motivating SO post). The type of the object argument fd is FD, where FD is decay_t<Func>, i.e. Func. That's it. For non-const object arguments, overload resolution prefers non-const member functions per se, hence we should e.g. get a diagnostic saying that a deleted function is called. Alternatively, some other construct inside bind should fail: libstdc++'s bind somehow requires result_of_t<Func&()>, which fails.
In short, this was never well-formed; the fact that it compiled is a consequence of the return type being denoted in an expression SFINAE manner.