Re: Revision of N3702: Introducing an optional parameter for mem_fn.

111 views
Skip to first unread message
Message has been deleted

toma...@gmail.com

unread,
Sep 21, 2013, 4:32:58 PM9/21/13
to std-pr...@isocpp.org
The paper has the same drawback as the first version of the my not_fn proposal. It will not work if the second argument is rvalue reference for move only type (ex. unique_ptr or jsut class object). Example:

std::men_fn(&C::f. std:make_unique<C>());

The solutions would be to change wording to:

template<class R, class T, class ObjT, class … Arg>

                            unspecified mem_fn(R T::* pm, ObjT&& obj);


//Here introduce names OjbTD for std::decay_t<ObjT> and objd for object constructed from std::forward<ObjT>(obj);


Requires: std::is_constructible<ObjTD, ObjT>::value is true.


Returns: A simple call wrapper (20.10.1) fn such that the expression fn(a1, ..., aN) is equivalent to INVOKE(pm, <del>obj</del> <ins>objd</ins>, a1,…aN).


Throws: Nothing unless construction of objd throws.

Remarks: //Info that returned object should be moveable and copyable if ObjTD is copyable.

For a detailed wording you may reference bind wording or my proposal https://github.com/tomaszkam/proposals/blob/master/A%20proposal%20to%20add%20a%20generalized%20callable%20negator.html

W dniu sobota, 21 września 2013 21:01:21 UTC+2 użytkownik Mikhail Semenov napisał:
The revised version has an improved implementation, which allows to pass objects, pointers to objects and smart pointers as the second parameter to mem_fn.

Message has been deleted

toma...@gmail.com

unread,
Sep 22, 2013, 9:25:02 AM9/22/13
to std-pr...@isocpp.org
W dniu niedziela, 22 września 2013 15:10:02 UTC+2 użytkownik Mikhail Semenov napisał:
Tomasz,
Well spotted.  I have put a revised version, which includes the support for unique pointers and reference wrappers for the second parameter.
 
Mikhail. 
There spelling mistake in the singature: the ObjT obj should become ObjT&& obj.
Message has been deleted

Mikhail Semenov

unread,
Sep 26, 2013, 3:42:11 PM9/26/13
to std-pr...@isocpp.org
Revised proposal: support for a unique pointer and reference wrapper as a second parameter is added, including a reference to a shared pointer. The second parameter is move-constructible.
 
mem_fn_revised.htm

Jeffrey Yasskin

unread,
Sep 29, 2013, 12:26:18 AM9/29/13
to std-pr...@isocpp.org
Thanks for the proposals. The Library Evolution group in Chicago
reviewed mem_fn and concluded that it's generally not worth extending
the callable wrappers, and that users should just use lambdas in
nearly all cases. C++14's generic lambdas with variadic captures make
this an even better tradeoff (note, I didn't compile this):

double r = integrate
([&a](const auto&... args) { return a.fa(args...);},
x1, x2, y1, y2, z1, z2, a1, a2, b1, b2);

http://wiki.edg.com/twiki/bin/view/Wg21chicago2013/N3702
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposal...@isocpp.org.
> To post to this group, send email to std-pr...@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.

Mikhail Semenov

unread,
Sep 29, 2013, 3:36:38 AM9/29/13
to std-pr...@isocpp.org
It can be done even better:
#define memb_delegate(_a, _f)\
  [&(_a)](auto&& ... _args) { return (_a)._f(std::forward<decltype(_args)>(_args)...);}
 
This can be used like this:
double r = integrate(member_delegate(a, fa),  x1, x2, y1, y2, z1, z2, a1, a2, b1, b2);
 
(I haven't compiled it either).
 
I works with various parameters.
 
I have mentioned it a couple of times during discussions.
 
By the way, I don't have access to twiki and failed to register.

toma...@gmail.com

unread,
Sep 29, 2013, 8:17:56 AM9/29/13
to std-pr...@isocpp.org


W dniu niedziela, 29 września 2013 06:26:18 UTC+2 użytkownik Jeffrey Yasskin napisał:
Thanks for the proposals. The Library Evolution group in Chicago
reviewed mem_fn and concluded that it's generally not worth extending
the callable wrappers, and that users should just use lambdas in
nearly all cases. C++14's generic lambdas with variadic captures make
this an even better tradeoff (note, I didn't compile this):

 double r = integrate
              ([&a](const auto&... args) { return a.fa(args...);},
                 x1, x2, y1, y2, z1, z2, a1, a2, b1, b2);

To work with any parameter/return (references) type combination, this should be written as:
 double r = integrate(
              [&a](auto&&... args) -> decltype(auto)
              { return a.fa(std::forward<decltype(auto)>(args)...); });


Which is pretty less readable and less intent clear than:
 double r = integrate(std::mem_fn(&A::a, std::ref(a)));

In my opinion the deifference between this 2 cases may be compared with the diference between using
hand-writtern loop versus algorithm.

toma...@gmail.com

unread,
Sep 29, 2013, 9:06:15 AM9/29/13
to std-pr...@isocpp.org

Also I think that requiring the programmer to use (and obviously know) varidatic templates (lambdas), value-categories (forward) and return type deduction
to do simple task of binding member function with the object (a.fo) is not a good direction if we want to make C++ more friendly.

"Make simple things simple".

Mikhail Semenov

unread,
Sep 29, 2013, 10:21:36 AM9/29/13
to std-pr...@isocpp.org
N3690, page 90, example:
 

return [=](auto&& ... ts) { // OK: ts is a function parameter pack
printer(std::forward<decltype(ts)>(ts)...);

...

 

The decltype(ts), not decltype(auto), otherwise the type is not clear.

 

As for the return -> decltype(auto), it was always optional for lambdas, especially it there is one return statement.

 

 

 

 

toma...@gmail.com

unread,
Sep 29, 2013, 10:35:27 AM9/29/13
to std-pr...@isocpp.org

The decltype(ts), not decltype(auto), otherwise the type is not clear.

That was a mistake.

As for the return -> decltype(auto), it was always optional for lambdas, especially it there is one return statement=


No, the return ->auto is optional. The return decltype(auto) is necessary if the wrapped function returns by reference - by default lambda will deduce return by value.

Mikhail Semenov

unread,
Sep 29, 2013, 10:37:33 AM9/29/13
to std-pr...@isocpp.org
>Also I think that requiring the programmer to use (and obviously know) varidatic templates (lambdas), value-categories (forward) and return type deduction
>to do simple task of binding member function with the object (
a.fo) is not a good direction if we want to make C++ more friendly.

>"Make simple things simple".
 
I agree with this point, the user has to do a lot in various areas:
 
(1) libraries, they often provide incomplete surrogate for the real product
(binary search does not return the index, you have to use lower_bound instead, adding extra checks);
(2) a lot was said in literature about istream iterators, which I find are practically unusable (you have to clear a lot of strange bits,
to start reading again);
(3) trimming is not done easily, you have to write something yourself;
(4) copy and move require a lot of extra writing, why not standardize swap, and allow move and copy constructors and assignments
to be derived from an empty constructor, a copy constructor and a swap operator; a lot of ugly and erroneous would be avoided.
 
 

 
Reply all
Reply to author
Forward
0 new messages