Prev: Template specialisation question
Next: C++ Compiler
From: Andy Venikov on 7 May 2010 03:15 Hi, Given: need to implement a perfect-forwarding function f. First attempt: template <typename Func, typename ... Prms> inline typename std::result_of<Func(Prms...)>::type f(Func && f, Prms && ... prms) { return f(std::forward<Prms>(prms)...); } The implementation seems reasonable - it'll be able to accept any callable entity, not just a function (i.e. it'll work with functors, function pointers, function references). I was wandering, if it was better to not directly return a call to f(...), but a moved version of it? I.e: return std::move(f(std::forward<Prms>(prms)...); When the returned objects are movable, this version seems more adequate. But is it safe? Thanks, Andy. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Andy Venikov on 8 May 2010 02:08 Andy Venikov wrote: > Hi, > > Given: need to implement a perfect-forwarding function f. > > First attempt: > > template <typename Func, typename ... Prms> > inline > typename std::result_of<Func(Prms...)>::type > f(Func && f, Prms && ... prms) > { > return f(std::forward<Prms>(prms)...); > } > > The implementation seems reasonable - it'll be able to accept any > callable entity, not just a function (i.e. it'll work with functors, > function pointers, function references). > > I was wandering, if it was better to not directly return a call to > f(...), but a moved version of it? > > I.e: > return std::move(f(std::forward<Prms>(prms)...); > > When the returned objects are movable, this version seems more adequate. > > But is it safe? > > Thanks, > Andy. > Well, after thinking about it more it looks like move serves no purpose. Since a return from a function is never an lvalue (either an rvalue or a reference), std::move in this context is just useless. Thanks anyway, Andy. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Howard Hinnant on 8 May 2010 02:12 On May 7, 2:15 pm, Andy Venikov <swojchelo...(a)gmail.com> wrote: > Hi, > > Given: need to implement a perfect-forwarding function f. > > First attempt: > > template <typename Func, typename ... Prms> > inline > typename std::result_of<Func(Prms...)>::type > f(Func && f, Prms && ... prms) > { > return f(std::forward<Prms>(prms)...); > > } > > The implementation seems reasonable - it'll be able to accept any callable entity, not just a function (i.e. it'll work with functors, function pointers, function references). > > I was wandering, if it was better to not directly return a call to f(...), but a moved version of it? > > I.e: > return std::move(f(std::forward<Prms>(prms)...); > > When the returned objects are movable, this version seems more adequate. > > But is it safe? If f() returns an rvalue, there is no need for std::move. All std::move() does is cast an expression to an rvalue. If f() returns an lvalue (such as an A&), you probably don't want to cast it to an rvalue as you might then end up implicitly moving from something you didn't intend (such as a data member if f() is a member function or has friend access to the data member). -Howard -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Mathias Gaunard on 8 May 2010 02:11 On 7 mai, 19:15, Andy Venikov <swojchelo...(a)gmail.com> wrote: > I was wandering, if it was better to not directly return a call to f(...), but a moved version of it? > > I.e: > return std::move(f(std::forward<Prms>(prms)...); > > When the returned objects are movable, this version seems more adequate. > > But is it safe? It is yes, but it is perfectly useless. Your expression is already a temporary. std::move is used to "transform" a named variable into a temporary. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: SG on 8 May 2010 02:12 On 7 Mai, 20:15, Andy Venikov wrote: > Hi, > > Given: need to implement a perfect-forwarding function f. > > First attempt: > > template <typename Func, typename ... Prms> > inline > typename std::result_of<Func(Prms...)>::type > f(Func && fun, Prms && ... prms) > { > return fun(std::forward<Prms>(prms)...); > } > > The implementation seems reasonable - it'll be able to accept any > callable entity, not just a function (i.e. it'll work with functors, > function pointers, function references). > > I was wondering, if it was better to not directly return a call to > fun(...), but a moved version of it? > > I.e: > return std::move(fun(std::forward<Prms>(prms)...); > > When the returned objects are movable, this version seems more adequate. Actually, it isn't "more adequate". If result_of<>::type is an object type, the function call is already an rvalue. The same is true if result_of<>::type is an rvalue reference type. In case result_of<>::type is an lvalue reference type, your modification won't compile because - move "converts" the lvalue to an rvalue - you try to initialize an lvalue reference (the return value of f) with an rvalue expression (the result of move). std::move does not need to be used on a function call expression -- unless the function returns an lvalue reference and you want to deliberately turn it into an rvalue. There are even situations where the use of std::move might prevent a compiler from doing a copy elision. Keep in mind that C++0x already forces a compiler to automatically move-construct objects in cases where copy elision is allowed but technically not possible and a move constructor is available. So, std::move should only be used if necessary. Cheers, SG -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: Template specialisation question Next: C++ Compiler |