From e8440e8855126312d568db2b7c99c4f050440999 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sat, 8 Sep 2012 13:54:41 +0000 Subject: [PATCH] Added result_of usage guideline. [SVN r80445] --- utility.htm | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/utility.htm b/utility.htm index 73bd692..09a8632 100644 --- a/utility.htm +++ b/utility.htm @@ -230,6 +230,51 @@ typedef boost::result_of< >::type type; // type is int +

The result template must be specialized for every valid calling signature of the function object. + If the operator() accepts arguments by (possibly const) reference and/or is const + qualified, the result specialization must take this into account. Type traits + and more generic specializations may help to reduce the number of result specializations. This way result_of users + will be able to specify argument types exactly according to the function object call expression. For example:

+ +
+
struct functor {
+    template<class> struct result;
+
+    // Use template parameter F to match the function object. This will allow result deduction for both const and non-const functor.
+    template<class F, class T>
+    struct result<F(T)> {
+        // When argument type is matched like above, remember that the type may be a (const-qualified) reference.
+        // Use type traits to transform the argument type.
+        typedef typename remove_cv<typename remove_reference<T>::type>::type argument_type;
+        typedef argument_type type;
+    };
+
+    // The operator can be called on both const and non-const functor. The argument can be lvalue or rvalue.
+    template<class T>
+    T operator()(T const& x) const
+    {
+        return x;
+    }
+};
+
+// All following result_of uses are valid and result in int
+typedef boost::result_of< functor(int) >::type type1; // the argument is rvalue
+functor f;
+type1 r1 = f(10);
+
+typedef boost::result_of< const functor(int) >::type type2; // the function object is const
+const functor cf;
+type2 r2 = cf(10);
+
+typedef boost::result_of< functor(int&) >::type type3; // the argument is lvalue
+int a = 10;
+type3 r3 = f(a);
+
+typedef boost::result_of< functor(int const&) >::type type4; // the argument is const lvalue
+const int ca = 10;
+type4 r4 = f(ca);
+
+

Since decltype is a new language feature recently standardized in C++11, if you are writing a function object