[Bug libstdc++/52917] [DR 2048] explicitly stated return type in std::mem_fn cannot be compiled

2014-05-07 Thread redi at gcc dot gnu.org
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

2012-04-10 Thread freunddeslichts at web dot de
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

2012-04-10 Thread redi at gcc dot gnu.org
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

2012-04-09 Thread redi at gcc dot gnu.org
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

2012-04-09 Thread redi at gcc dot gnu.org
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++