mirror of
https://github.com/boostorg/utility.git
synced 2025-07-29 20:37:32 +02:00
boost::result_of uses decltype on compilers that implement N3276, merges [77905], [78195], [80352] from trunk
[SVN r80355]
This commit is contained in:
@ -66,7 +66,7 @@ struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
|
||||
} // 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))
|
||||
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)> { };
|
||||
#endif
|
||||
|
||||
#endif // defined(BOOST_NO_DECLTYPE)
|
||||
#endif // !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||
|
||||
#undef BOOST_RESULT_OF_ARGS
|
||||
|
||||
|
@ -30,6 +30,24 @@
|
||||
# define BOOST_RESULT_OF_NUM_ARGS 10
|
||||
#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 {
|
||||
|
||||
template<typename F> struct result_of;
|
||||
|
@ -5,7 +5,7 @@
|
||||
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// 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
|
||||
#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);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct cv_overload_check {};
|
||||
|
||||
struct result_of_member_function_template
|
||||
{
|
||||
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<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<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<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<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);
|
||||
};
|
||||
|
||||
struct no_result_type_or_result_of
|
||||
struct no_result_type_or_result
|
||||
{
|
||||
int operator()(double);
|
||||
short operator()(double) const;
|
||||
unsigned int operator()();
|
||||
unsigned short operator()() volatile;
|
||||
const unsigned short operator()() const volatile;
|
||||
short operator()(double);
|
||||
cv_overload_check<const short> operator()(double) const;
|
||||
cv_overload_check<volatile short> operator()(double) volatile;
|
||||
cv_overload_check<const volatile short> operator()(double) 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)
|
||||
short operator()(int&&);
|
||||
int operator()(int&);
|
||||
@ -106,13 +112,16 @@ struct no_result_type_or_result_of
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct no_result_type_or_result_of_template
|
||||
struct no_result_type_or_result_template
|
||||
{
|
||||
int operator()(double);
|
||||
short operator()(double) const;
|
||||
unsigned int operator()();
|
||||
unsigned short operator()() volatile;
|
||||
const unsigned short operator()() const volatile;
|
||||
short operator()(double);
|
||||
cv_overload_check<const short> operator()(double) const;
|
||||
cv_overload_check<volatile short> operator()(double) volatile;
|
||||
cv_overload_check<const volatile short> operator()(double) 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)
|
||||
short operator()(int&&);
|
||||
int operator()(int&);
|
||||
@ -157,7 +166,7 @@ int main()
|
||||
|
||||
// Prior to decltype, result_of could not deduce the return 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<volatile int_result_of(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));
|
||||
#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
|
||||
// result_type was defined. After decltype, result_of deduces the
|
||||
// actual return type of the function object, ignoring both
|
||||
// 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_template<void>(char)>::type, char>::value));
|
||||
#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));
|
||||
#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_ref(char, float)>::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<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<volatile result_of_member_function_template(double)>::type, 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 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, cv_overload_check<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 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 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<const result_of_member_function_template(double)>::type, 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<const volatile result_of_member_function_template(double)>::type, const volatile 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, cv_overload_check<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 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));
|
||||
@ -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 const(int)>::type,int>::value));
|
||||
|
||||
#if !defined(BOOST_NO_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_of(void)>::type, unsigned int>::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_of(void)>::type, unsigned 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_of_template<void>(double)>::type, 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<const no_result_type_or_result_of_template<void>(double)>::type, short>::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));
|
||||
#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(double)>::type, short>::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<volatile no_result_type_or_result(double)>::type, cv_overload_check<volatile 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<no_result_type_or_result(void)>::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<volatile no_result_type_or_result(void)>::type, cv_overload_check<volatile int> >::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<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)
|
||||
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_of(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_of_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_of_template<void>(int const&)>::type, long>::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(int&)>::type, int>::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_template<void>(int&&)>::type, short>::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_template<void>(int const&)>::type, long>::value));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
61
utility.htm
61
utility.htm
@ -161,14 +161,12 @@ void f() {
|
||||
resides in the header <code><<a
|
||||
href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.</p>
|
||||
|
||||
<p>If your compiler supports <code>decltype</code>,
|
||||
then you can enable automatic result type deduction by
|
||||
defining the macro <code>BOOST_RESULT_OF_USE_DECLTYPE</code>,
|
||||
as in the following example.</p>
|
||||
<p>If your compiler's support for <code>decltype</code> is
|
||||
adequate, <code>result_of</code> automatically uses it to
|
||||
deduce the result type of your callable object.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#include <boost/utility/result_of.hpp>
|
||||
<pre>#include <boost/utility/result_of.hpp>
|
||||
|
||||
struct functor {
|
||||
template<class T>
|
||||
@ -180,21 +178,29 @@ struct functor {
|
||||
|
||||
typedef boost::result_of<
|
||||
functor(int)
|
||||
>::type type;</pre>
|
||||
>::type type; // type is int</pre>
|
||||
</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
|
||||
objects is not possible. Instead, <code>result_of</code>
|
||||
uses the following protocol to allow the programmer to
|
||||
specify a type. When <code>F</code> is a class type with a
|
||||
member type <code>result_type</code>,
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)></code> is
|
||||
T<em>N</em>)>::type</code> is
|
||||
<code>F::result_type</code>. When <code>F</code> does
|
||||
not contain <code>result_type</code>,
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)></code> is <code>F::result<F(T1,
|
||||
T<em>N</em>)>::type</code> is <code>F::result<F(T1,
|
||||
T2, ..., T<em>N</em>)>::type</code> when
|
||||
<code><em>N</em> > 0</code> or <code>void</code>
|
||||
when <code><em>N</em> = 0</code>. Note that it is the
|
||||
@ -221,22 +227,29 @@ typedef boost::result_of<
|
||||
|
||||
typedef boost::result_of<
|
||||
functor(int)
|
||||
>::type type;</pre>
|
||||
>::type type; // type is int</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>In a future
|
||||
release, <code>BOOST_RESULT_OF_USE_DECLTYPE</code>
|
||||
may be enabled by default on compilers that
|
||||
support <code>decltype</code>, so if you use the above
|
||||
protocol please take care to ensure that
|
||||
the <code>result_type</code>
|
||||
and <code>result<></code> members accurately
|
||||
represent the result type. If you wish to continue to
|
||||
<p>Since <code>decltype</code> is a new language
|
||||
feature recently standardized in C++11,
|
||||
if you are writing a function object
|
||||
to be used with <code>result_of</code>, for
|
||||
maximum portability, you might consider following
|
||||
the above protocol even if your compiler has
|
||||
proper <code>decltype</code> support. If you wish to continue to
|
||||
use the protocol on compilers that
|
||||
support <code>decltype</code>,
|
||||
use <code>boost::tr1_result_of</code>, which is also
|
||||
defined
|
||||
in <code><<a href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.</p>
|
||||
support <code>decltype</code>, there are two options:
|
||||
You can use <code>boost::tr1_result_of</code>, which is also
|
||||
defined in <code><<a href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.
|
||||
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<></code> members accurately
|
||||
represent the return type of
|
||||
<code>operator()</code>.</p>
|
||||
|
||||
<a name="BOOST_NO_RESULT_OF"></a>
|
||||
<p>This implementation of <code>result_of</code>
|
||||
@ -253,7 +266,7 @@ typedef boost::result_of<
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>,
|
||||
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>
|
||||
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>
|
||||
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
|
||||
|
Reference in New Issue
Block a user