Re: [boost] [result_of] Usage guidelines

Ok, here is my second take on this. I've attached a patch with my changes. 1. I moved the guidelines to a separate section in order not to clutter the formal result_of description. 2. I seperately outlined the C++11 and C++03 recommendations. 3. I left the result_of examples. I think they illustrate the result_of usage quite well, but I'll be happy if someone comes up with something better. 4. I rephrased some of the wording about result<> usage, in response to Jeffrey's reply. Comments are welcome.

On Saturday 08 September 2012 22:34:30 you wrote:
Ok, here is my second take on this. I've attached a patch with my changes.
1. I moved the guidelines to a separate section in order not to clutter the formal result_of description. 2. I seperately outlined the C++11 and C++03 recommendations. 3. I left the result_of examples. I think they illustrate the result_of usage quite well, but I'll be happy if someone comes up with something better. 4. I rephrased some of the wording about result<> usage, in response to Jeffrey's reply.
Comments are welcome.
Any comments? Daniel?

On Sep 11, 2012, at 2:22 AM, Andrey Semashev wrote:
On Saturday 08 September 2012 22:34:30 you wrote:
Ok, here is my second take on this. I've attached a patch with my changes.
1. I moved the guidelines to a separate section in order not to clutter the formal result_of description. 2. I seperately outlined the C++11 and C++03 recommendations. 3. I left the result_of examples. I think they illustrate the result_of usage quite well, but I'll be happy if someone comes up with something better. 4. I rephrased some of the wording about result<> usage, in response to Jeffrey's reply.
Comments are welcome.
Any comments? Daniel?
Thanks Andrey. I like your idea of moving the guidelines to a different section and separating out C++03 details. Along those lines, I added two sections to the documentation: one for general usage guidelines and and one for TR1 specific guidelines. I also add a section describing known differences between decltype-based boost::restult_of and TR1 and another short section for differences between decltype-based boost::result_of and C++11. I also incorporated your example using the Boost.TypeTraits library to simplify a result specialization. There were many good comments and suggestions in this and the other thread, and I tried to incorporate them all. The new documentation is on trunk as of revision [80535]. - Daniel

Daniel Walker wrote:
There were many good comments and suggestions in this and the other thread, and I tried to incorporate them all. The new documentation is on trunk as of revision [80535].
This is really nice work. Thanks all! One comment: In C++11, a (non-static) member function can have ref-qualifiers. Currently this feature is only supported in clang 2.9 and later versions (in a C++11 mode). So it might not be worth mentioning in the doc. But anyway, here is a sample code: struct functor { char& operator()() &; char&& operator()() &&; }; typedef boost::result_of< functor&()
::type type5; // type5 is char &
typedef boost::result_of< functor&&()
::type type6; // type6 is char &&
typedef boost::result_of< functor()
::type type7; // type7 is char &&
Regards, Michel

On Sat, Sep 8, 2012 at 11:34 AM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
Ok, here is my second take on this. I've attached a patch with my changes.
1. I moved the guidelines to a separate section in order not to clutter the formal result_of description. 2. I seperately outlined the C++11 and C++03 recommendations. 3. I left the result_of examples. I think they illustrate the result_of usage quite well, but I'll be happy if someone comes up with something better. 4. I rephrased some of the wording about result<> usage, in response to Jeffrey's reply.
Comments are welcome.
Regarding the signature one instantiates result_of with, the present Boost.ResultOf documentation states that result_of< F ( T ) >::type is the result of f(t) where f is an *lvalue* of type F and t is an *lvalue* of type T. I've personally always found this needlessly limiting (precludes deducing strictly correct result types for rvalue arguments), and it appears to contradict what is expressed in this patch. I understand this patch as strictly an addition to the present documentation, so I wonder if it is appropriate to alter the existing Boost.ResultOf documentation text to reflect these "new" usage guidelines (specifically, distinguishing between lvalue and rvalue parameters). "No additional scaffolding is needed from function objects, the compiler will ..." comma should be a semicolon Regarding the example functor struct and the result specialization therein, I like calling the first template parameter "This", to denote that it should be approximately the same type as the enclosing class: template< class > struct result; template< class This, class T > struct result< This ( T ) > { typedef ... type; }; Just a suggestion. Regarding the use of "remove_cv< remove_reference<T>::type >::type", I think this is pretty much what std::decay [1] was designed for (I hadn't realized this existed until recently). boost::decay [2] is almost but not quite functionally identical; perhaps it can be modified to add an additional remove_cv (or does it do that already, and the boost::decay docs just need to be tweaked)? Then Andrey's example would look a little cleaner. - Jeff [1] http://en.cppreference.com/w/cpp/types/decay [2] http://www.boost.org/doc/libs/1_51_0/libs/type_traits/doc/html/boost_typetra...

On Wednesday 12 September 2012 07:31:34 Jeffrey Lee Hellrung, Jr. wrote:
Regarding the signature one instantiates result_of with, the present Boost.ResultOf documentation states that result_of< F ( T ) >::type is the result of f(t) where f is an *lvalue* of type F and t is an *lvalue* of type T. I've personally always found this needlessly limiting (precludes deducing strictly correct result types for rvalue arguments), and it appears to contradict what is expressed in this patch. I understand this patch as strictly an addition to the present documentation, so I wonder if it is appropriate to alter the existing Boost.ResultOf documentation text to reflect these "new" usage guidelines (specifically, distinguishing between lvalue and rvalue parameters).
Good catch, I missed that limitation in the formal result_of description. Indeed, with the current wording the meaning of result_of<f(int)>::type is unclear. std::result_of<F(T)> is defined in terms of std::declval<T>() which effectively means that when T is not a lvalue reference, the argument is assumed to be rvalue. This is outlined in the guidelines and I think, the formal description should be updated accordingly, unless there are some background reasons not to.
"No additional scaffolding is needed from function objects, the compiler will ..." comma should be a semicolon
Will do.
Regarding the example functor struct and the result specialization therein, I like calling the first template parameter "This", to denote that it should be approximately the same type as the enclosing class:
template< class > struct result; template< class This, class T > struct result< This ( T ) > { typedef ... type; };
Just a suggestion.
Ok, I just followed the pattern of the previous examples.
Regarding the use of "remove_cv< remove_reference<T>::type >::type", I think this is pretty much what std::decay [1] was designed for (I hadn't realized this existed until recently). boost::decay [2] is almost but not quite functionally identical; perhaps it can be modified to add an additional remove_cv (or does it do that already, and the boost::decay docs just need to be tweaked)? Then Andrey's example would look a little cleaner.
boost::decay doesn't do remove_cv, so it can't be used as a replacement. It should probably be updated to reflect std::decay, but until then remove_cv+remove_reference will have to stay, I guess.

On Sep 12, 2012, at 11:16 AM, Andrey Semashev wrote:
On Wednesday 12 September 2012 07:31:34 Jeffrey Lee Hellrung, Jr. wrote:
Regarding the signature one instantiates result_of with, the present Boost.ResultOf documentation states that result_of< F ( T ) >::type is the result of f(t) where f is an *lvalue* of type F and t is an *lvalue* of type T. I've personally always found this needlessly limiting (precludes deducing strictly correct result types for rvalue arguments), and it appears to contradict what is expressed in this patch. I understand this patch as strictly an addition to the present documentation, so I wonder if it is appropriate to alter the existing Boost.ResultOf documentation text to reflect these "new" usage guidelines (specifically, distinguishing between lvalue and rvalue parameters).
Good catch, I missed that limitation in the formal result_of description. Indeed, with the current wording the meaning of result_of<f(int)>::type is unclear.
std::result_of<F(T)> is defined in terms of std::declval<T>() which effectively means that when T is not a lvalue reference, the argument is assumed to be rvalue. This is outlined in the guidelines and I think, the formal description should be updated accordingly, unless there are some background reasons not to.
The statement regarding the objects being lvalues is from the original documentation and should really only serve as an example these days. I changed that part of the documentation to refer to it as such; i.e. an example not a restrictive definition. I also added a reference to the more formal/explicit decltype(declval<f>()(declval<T>(),...)) expression. - Daniel
participants (4)
-
Andrey Semashev
-
Daniel Walker
-
Jeffrey Lee Hellrung, Jr.
-
Michel Morin