[Bug libstdc++/52917] [DR 2048] explicitly stated return type in std::mem_fn cannot be compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52917 Jonathan Wakely redi at gcc dot gnu.org changed: What|Removed |Added Status|SUSPENDED |RESOLVED Resolution|--- |INVALID --- Comment #5 from Jonathan Wakely redi at gcc dot gnu.org --- The standard agrees with libstdc++ now, so this is invalid.
[Bug libstdc++/52917] [DR 2048] explicitly stated return type in std::mem_fn cannot be compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52917 --- Comment #3 from freunddeslichts at web dot de 2012-04-10 09:54:28 UTC --- Ok, I didn't know about the defect report and resolution yet. I must admit that I quite like the int() syntax. I added a remark about the defect and a short example to http://en.cppreference.com/w/cpp/utility/functional/mem_fn And I noted that the most c++11-ish code would be anyway: auto y = [] (X x) {return x.get();};
[Bug libstdc++/52917] [DR 2048] explicitly stated return type in std::mem_fn cannot be compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52917 --- Comment #4 from Jonathan Wakely redi at gcc dot gnu.org 2012-04-10 11:23:51 UTC --- (In reply to comment #3) Ok, I didn't know about the defect report and resolution yet. I must admit that I quite like the int() syntax. It's a peculiarity of the C++ grammar, the function parameter R T::*pm is a pointer to member, with T deduced as X and R deduced as the function type int() If it helps, consider that you can declare X::get() like this: #include functional struct X { int a; typedef int func_type(); func_type get; }; int X::get() { return a; } And then you can use the typedef with mem_fn: auto pm = std::mem_fnX::func_type(X::get); I added a remark about the defect and a short example to http://en.cppreference.com/w/cpp/utility/functional/mem_fn N.B. That page has a heading Execptions And I noted that the most c++11-ish code would be anyway: auto y = [] (X x) {return x.get();}; In most cases yes, but mem_fn has the advantage it always returns the same type, whereas two lambda expressions produce two different closure types even if the expressions are identical, and mem_fn might be easier to use in late-specified return types.
[Bug libstdc++/52917] [DR 2048] explicitly stated return type in std::mem_fn cannot be compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52917 Jonathan Wakely redi at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |SUSPENDED Last reconfirmed||2012-04-09 Summary|explicitly stated return|[DR 2048] explicitly stated |type in std::mem_fn cannot |return type in std::mem_fn |be compiled |cannot be compiled Ever Confirmed|0 |1 --- Comment #1 from Jonathan Wakely redi at gcc dot gnu.org 2012-04-09 21:18:11 UTC --- (In reply to comment #0) (2) needs the return type to diffrentiate between the const and the non-const getter. Or you can do auto y = std::mem_fn((int (X::*)())X::get ); Which also works in this case where specifying the return type doesn't help: struct X { int get() { return 0; } int get() const { return 1; } }; The specification for mem_fn is template class R, class T /*unspecified*/ mem_fn(R T::* pm); template class R, class T, class... Args /*unspecified*/ mem_fn(R (T::* pm)(Args...)); [ ... some more overloads for const, volatile and references] Maybe not for long: http://cplusplus.github.com/LWG/lwg-active.html#2048 The libstdc++ implementation exactly matches that issue's proposed resolution, which has been voted Tentatively Ready. (2) should result in an instantiation of the second version with sizeof...(Args)==0, because argument to the first version is a pointer to member data, not pointer to member function. No, it's a pointer to member, which can match either a pointer to member data or pointer to member function. If the second overload exists (as it presumably does in libc++) then it's a better match than the first overload, but the first overload is still viable. Both g++-4.7 and clang++-3.1 (when compiling with libstdc++) try to instantiate the first version by mistake. Not by mistake, by design, that overload can match any pointer to member. I'm suspending this because I believe the resolution to DR 2048 would make libstdc++ correct.
[Bug libstdc++/52917] [DR 2048] explicitly stated return type in std::mem_fn cannot be compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52917 --- Comment #2 from Jonathan Wakely redi at gcc dot gnu.org 2012-04-09 21:35:07 UTC --- (In reply to comment #1) Or you can do auto y = std::mem_fn((int (X::*)())X::get ); Or auto y = std::mem_fn int()(X::get ); Which should also work with either libstdc++ or libc++