boost::result_of uses decltype on compilers that implement N3276, merges [77905], [78195], [80352] from trunk

[SVN r80355]
This commit is contained in:
Eric Niebler
2012-09-01 23:12:32 +00:00
parent fb2d391928
commit a89b0101fc
4 changed files with 117 additions and 70 deletions

View File

@ -66,7 +66,7 @@ struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
} // namespace detail } // namespace detail
#else // defined(BOOST_NO_DECLTYPE) #else // !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE)
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
@ -75,7 +75,7 @@ struct result_of<F(BOOST_RESULT_OF_ARGS)>
: tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { }; : tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { };
#endif #endif
#endif // defined(BOOST_NO_DECLTYPE) #endif // !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE)
#undef BOOST_RESULT_OF_ARGS #undef BOOST_RESULT_OF_ARGS

View File

@ -30,6 +30,24 @@
# define BOOST_RESULT_OF_NUM_ARGS 10 # define BOOST_RESULT_OF_NUM_ARGS 10
#endif #endif
// Use the decltype-based version of result_of by default if the compiler
// supports N3276 <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3276.pdf>.
// The user can force the choice by defining either BOOST_RESULT_OF_USE_DECLTYPE or
// BOOST_RESULT_OF_USE_TR1, but not both!
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)
# error Both BOOST_RESULT_OF_USE_DECLTYPE and BOOST_RESULT_OF_USE_TR1 cannot be defined at the same time.
#endif
#ifndef BOOST_RESULT_OF_USE_TR1
# ifndef BOOST_RESULT_OF_USE_DECLTYPE
# ifndef BOOST_NO_DECLTYPE_N3276 // this implies !defined(BOOST_NO_DECLTYPE)
# define BOOST_RESULT_OF_USE_DECLTYPE
# else
# define BOOST_RESULT_OF_USE_TR1
# endif
# endif
#endif
namespace boost { namespace boost {
template<typename F> struct result_of; template<typename F> struct result_of;

View File

@ -5,7 +5,7 @@
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_RESULT_OF_USE_DECLTYPE #include <boost/config.hpp>
// For more information, see http://www.boost.org/libs/utility // For more information, see http://www.boost.org/libs/utility
#include <boost/utility/result_of.hpp> #include <boost/utility/result_of.hpp>
@ -62,6 +62,9 @@ struct int_result_type_and_float_result_of_and_char_return_template
char operator()(char); char operator()(char);
}; };
template<typename T>
struct cv_overload_check {};
struct result_of_member_function_template struct result_of_member_function_template
{ {
template<typename F> struct result; template<typename F> struct result;
@ -69,13 +72,13 @@ struct result_of_member_function_template
template<typename This, typename That> struct result<This(That)> { typedef That type; }; template<typename This, typename That> struct result<This(That)> { typedef That type; };
template<class T> typename result<result_of_member_function_template(T)>::type operator()(T); template<class T> typename result<result_of_member_function_template(T)>::type operator()(T);
template<typename This, typename That> struct result<const This(That)> { typedef const That type; }; template<typename This, typename That> struct result<const This(That)> { typedef cv_overload_check<const That> type; };
template<class T> typename result<const result_of_member_function_template(T)>::type operator()(T) const; template<class T> typename result<const result_of_member_function_template(T)>::type operator()(T) const;
template<typename This, typename That> struct result<volatile This(That)> { typedef volatile That type; }; template<typename This, typename That> struct result<volatile This(That)> { typedef cv_overload_check<volatile That> type; };
template<class T> typename result<volatile result_of_member_function_template(T)>::type operator()(T) volatile; template<class T> typename result<volatile result_of_member_function_template(T)>::type operator()(T) volatile;
template<typename This, typename That> struct result<const volatile This(That)> { typedef const volatile That type; }; template<typename This, typename That> struct result<const volatile This(That)> { typedef cv_overload_check<const volatile That> type; };
template<class T> typename result<const volatile result_of_member_function_template(T)>::type operator()(T) const volatile; template<class T> typename result<const volatile result_of_member_function_template(T)>::type operator()(T) const volatile;
template<typename This, typename That> struct result<This(That &, That)> { typedef That & type; }; template<typename This, typename That> struct result<This(That &, That)> { typedef That & type; };
@ -91,13 +94,16 @@ struct result_of_member_function_template
template<class T> typename result<result_of_member_function_template(T const volatile &, T)>::type operator()(T const volatile &, T); template<class T> typename result<result_of_member_function_template(T const volatile &, T)>::type operator()(T const volatile &, T);
}; };
struct no_result_type_or_result_of struct no_result_type_or_result
{ {
int operator()(double); short operator()(double);
short operator()(double) const; cv_overload_check<const short> operator()(double) const;
unsigned int operator()(); cv_overload_check<volatile short> operator()(double) volatile;
unsigned short operator()() volatile; cv_overload_check<const volatile short> operator()(double) const volatile;
const unsigned short operator()() const volatile; int operator()();
cv_overload_check<const int> operator()() const;
cv_overload_check<volatile int> operator()() volatile;
cv_overload_check<const volatile int> operator()() const volatile;
#if !defined(BOOST_NO_RVALUE_REFERENCES) #if !defined(BOOST_NO_RVALUE_REFERENCES)
short operator()(int&&); short operator()(int&&);
int operator()(int&); int operator()(int&);
@ -106,13 +112,16 @@ struct no_result_type_or_result_of
}; };
template<typename T> template<typename T>
struct no_result_type_or_result_of_template struct no_result_type_or_result_template
{ {
int operator()(double); short operator()(double);
short operator()(double) const; cv_overload_check<const short> operator()(double) const;
unsigned int operator()(); cv_overload_check<volatile short> operator()(double) volatile;
unsigned short operator()() volatile; cv_overload_check<const volatile short> operator()(double) const volatile;
const unsigned short operator()() const volatile; int operator()();
cv_overload_check<const int> operator()() const;
cv_overload_check<volatile int> operator()() volatile;
cv_overload_check<const volatile int> operator()() const volatile;
#if !defined(BOOST_NO_RVALUE_REFERENCES) #if !defined(BOOST_NO_RVALUE_REFERENCES)
short operator()(int&&); short operator()(int&&);
int operator()(int&); int operator()(int&);
@ -157,7 +166,7 @@ int main()
// Prior to decltype, result_of could not deduce the return type // Prior to decltype, result_of could not deduce the return type
// nullary function objects unless they exposed a result_type. // nullary function objects unless they exposed a result_type.
#if !defined(BOOST_NO_DECLTYPE) #if defined(BOOST_RESULT_OF_USE_DECLTYPE)
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, int>::value));
@ -169,14 +178,11 @@ int main()
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value)); BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
#endif #endif
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
// Prior to decltype, result_of ignored a nested result<> if // Prior to decltype, result_of ignored a nested result<> if
// result_type was defined. After decltype, result_of deduces the // result_type was defined. After decltype, result_of deduces the
// actual return type of the function object, ignoring both // actual return type of the function object, ignoring both
// result<> and result_type. // result<> and result_type.
#if !defined(BOOST_NO_DECLTYPE) #if defined(BOOST_RESULT_OF_USE_DECLTYPE)
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value));
#else #else
@ -184,6 +190,9 @@ int main()
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
#endif #endif
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value));
@ -207,18 +216,18 @@ int main()
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(void)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(double)>::type, double>::value)); BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(double)>::type, double>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const result_of_member_function_template(double)>::type, const double>::value)); BOOST_STATIC_ASSERT((is_same<result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile result_of_member_function_template(double)>::type, volatile double>::value)); BOOST_STATIC_ASSERT((is_same<result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile result_of_member_function_template(double)>::type, const volatile double>::value)); BOOST_STATIC_ASSERT((is_same<result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int &, int)>::type, int &>::value)); BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value)); BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value)); BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value)); BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(double)>::type, double>::value)); BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(double)>::type, double>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, const double>::value)); BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, volatile double>::value)); BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, const volatile double>::value)); BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int &, int)>::type, int &>::value)); BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value)); BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value)); BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
@ -231,24 +240,31 @@ int main()
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value)); BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value));
#if !defined(BOOST_NO_DECLTYPE) #if defined(BOOST_RESULT_OF_USE_DECLTYPE)
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(double)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(double)>::type, short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(void)>::type, unsigned int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(double)>::type, cv_overload_check<const short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_of(double)>::type, short>::value)); BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(double)>::type, cv_overload_check<volatile short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_of(void)>::type, unsigned short>::value)); BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(double)>::type, cv_overload_check<const volatile short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_of(void)>::type, const unsigned short>::value)); BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(double)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(void)>::type, cv_overload_check<const int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(void)>::type, unsigned int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(void)>::type, cv_overload_check<volatile int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_of_template<void>(double)>::type, short>::value)); BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(void)>::type, cv_overload_check<const volatile int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_of_template<void>(void)>::type, unsigned short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_of_template<void>(void)>::type, const unsigned short>::value)); BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(double)>::type, short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<volatile short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const volatile short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<volatile int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const volatile int> >::value));
#if !defined(BOOST_NO_RVALUE_REFERENCES) #if !defined(BOOST_NO_RVALUE_REFERENCES)
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int&&)>::type, short>::value)); BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&&)>::type, short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int&)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int const&)>::type, long>::value)); BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int const&)>::type, long>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int&&)>::type, short>::value)); BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&&)>::type, short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int&)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int const&)>::type, long>::value)); BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int const&)>::type, long>::value));
#endif #endif
#endif #endif

View File

@ -161,14 +161,12 @@ void f() {
resides in the header <code>&lt;<a resides in the header <code>&lt;<a
href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>&gt;</code>.</p> href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>&gt;</code>.</p>
<p>If your compiler supports <code>decltype</code>, <p>If your compiler's support for <code>decltype</code> is
then you can enable automatic result type deduction by adequate, <code>result_of</code> automatically uses it to
defining the macro <code>BOOST_RESULT_OF_USE_DECLTYPE</code>, deduce the result type of your callable object.</p>
as in the following example.</p>
<blockquote> <blockquote>
<pre>#define BOOST_RESULT_OF_USE_DECLTYPE <pre>#include &lt;boost/utility/result_of.hpp&gt;
#include &lt;boost/utility/result_of.hpp&gt;
struct functor { struct functor {
template&lt;class T&gt; template&lt;class T&gt;
@ -180,21 +178,29 @@ struct functor {
typedef boost::result_of&lt; typedef boost::result_of&lt;
functor(int) functor(int)
&gt;::type type;</pre> &gt;::type type; // type is int</pre>
</blockquote> </blockquote>
<p>If <code>decltype</code> is not enabled, <p>You can test whether <code>result_of</code> is using
<code>decltype</code> by checking if the macro
<code>BOOST_RESULT_OF_USE_DECLTYPE</code> is defined after
including <code>result_of.hpp</code>. You can also force
<code>result_of</code> to use <code>decltype</code> by
defining <code>BOOST_RESULT_OF_USE_DECLTYPE</code> prior
to including <code>result_of.hpp</code>.</p>
<p>If <code>decltype</code> is not used,
then automatic result type deduction of function then automatic result type deduction of function
objects is not possible. Instead, <code>result_of</code> objects is not possible. Instead, <code>result_of</code>
uses the following protocol to allow the programmer to uses the following protocol to allow the programmer to
specify a type. When <code>F</code> is a class type with a specify a type. When <code>F</code> is a class type with a
member type <code>result_type</code>, member type <code>result_type</code>,
<code>result_of&lt;F(T1, T2, ..., <code>result_of&lt;F(T1, T2, ...,
T<em>N</em>)&gt;</code> is T<em>N</em>)&gt;::type</code> is
<code>F::result_type</code>. When <code>F</code> does <code>F::result_type</code>. When <code>F</code> does
not contain <code>result_type</code>, not contain <code>result_type</code>,
<code>result_of&lt;F(T1, T2, ..., <code>result_of&lt;F(T1, T2, ...,
T<em>N</em>)&gt;</code> is <code>F::result&lt;F(T1, T<em>N</em>)&gt;::type</code> is <code>F::result&lt;F(T1,
T2, ..., T<em>N</em>)&gt;::type</code> when T2, ..., T<em>N</em>)&gt;::type</code> when
<code><em>N</em> &gt; 0</code> or <code>void</code> <code><em>N</em> &gt; 0</code> or <code>void</code>
when <code><em>N</em> = 0</code>. Note that it is the when <code><em>N</em> = 0</code>. Note that it is the
@ -221,22 +227,29 @@ typedef boost::result_of&lt;
typedef boost::result_of&lt; typedef boost::result_of&lt;
functor(int) functor(int)
&gt;::type type;</pre> &gt;::type type; // type is int</pre>
</blockquote> </blockquote>
<p>In a future <p>Since <code>decltype</code> is a new language
release, <code>BOOST_RESULT_OF_USE_DECLTYPE</code> feature recently standardized in C++11,
may be enabled by default on compilers that if you are writing a function object
support <code>decltype</code>, so if you use the above to be used with <code>result_of</code>, for
protocol please take care to ensure that maximum portability, you might consider following
the <code>result_type</code> the above protocol even if your compiler has
and <code>result&lt;&gt;</code> members accurately proper <code>decltype</code> support. If you wish to continue to
represent the result type. If you wish to continue to
use the protocol on compilers that use the protocol on compilers that
support <code>decltype</code>, support <code>decltype</code>, there are two options:
use <code>boost::tr1_result_of</code>, which is also You can use <code>boost::tr1_result_of</code>, which is also
defined defined in <code>&lt;<a href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>&gt;</code>.
in <code>&lt;<a href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>&gt;</code>.</p> Alternatively, you can define the macro
<code>BOOST_RESULT_OF_USE_TR1</code>, which causes
<code>result_of</code> to use the protocol described
above instead of <code>decltype</code>. If you choose to
follow the protocol, take care to ensure that the
<code>result_type</code> and
<code>result&lt;&gt;</code> members accurately
represent the return type of
<code>operator()</code>.</p>
<a name="BOOST_NO_RESULT_OF"></a> <a name="BOOST_NO_RESULT_OF"></a>
<p>This implementation of <code>result_of</code> <p>This implementation of <code>result_of</code>
@ -253,7 +266,7 @@ typedef boost::result_of&lt;
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>,
or, for motivation and design rationale, or, for motivation and design rationale,
the <code>result_of</code> <a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p> the <code>result_of</code> <a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p>
Contributed by Doug Gregor.</p> <p>Created by Doug Gregor. Contributions from Daniel Walker, Eric Niebler, Michel Morin and others</p>
<h2>Class templates for the Base-from-Member Idiom</h2> <h2>Class templates for the Base-from-Member Idiom</h2>
<p>See <a href="base_from_member.html">separate documentation</a>.</p> <p>See <a href="base_from_member.html">separate documentation</a>.</p>