
On Thu, Jul 3, 2008 at 12:06 AM, David Abrahams <dave@boostpro.com> wrote:
Giovanni Piero Deretta wrote:
On Wed, Jul 2, 2008 at 8:40 PM, Eric Niebler <eric@boost-consulting.com> wrote:
I don't know a sufficiently portable way to ask a type whether it has implemented the result_of protocol. In C++0x, result_of will simply use decltype, so at the very least Phoenix's approach is forward-compatible.
With 'portable' you mean 'works with non completely compliant compilers'? Otherwise I think you can legally sfinae on the presence of both result<> and result_type.
Demonstration, please. I don't know of a way to detect a nested template with SFINAE.
Daniel Walker posted a patch sometime ago to add BOOST_HAS_TEMPLATE_XXX to mpl. Here is a link: http://svn.boost.org/trac/boost/ticket/861 I'm sure that Eric is aware of it (and you too actually :) ) but IIRC he feared the amount of compiler workarounds. I use a variant of this to dinstinguish between 'sig' and 'result' and work fairly well on gcc 3.3 and 4.x. Here is a short test: #include <boost/static_assert.hpp> typedef char true_type[2]; typedef char false_type[1]; false_type& test(...); template<class T, class T2> struct dummy{}; template<class T1, class T2> true_type& test(dummy<T1, T2>, typename T1:: template result<T2>* =0); struct foo {}; struct bar { template<typename T> struct result{}; }; struct baz { int result; }; struct barf { typedef int result; }; struct bas { template<class T1, class T2> struct result{} ; }; struct bax { template<class T1, class T2=void> struct result{} ; }; BOOST_STATIC_ASSERT(sizeof(test(dummy<foo, int()>())) == sizeof(false_type)); BOOST_STATIC_ASSERT(sizeof(test(dummy<bar, int()>())) == sizeof(true_type)); BOOST_STATIC_ASSERT(sizeof(test(dummy<baz, int()>())) == sizeof(false_type)); BOOST_STATIC_ASSERT(sizeof(test(dummy<barf, int()>())) == sizeof(false_type)); //BOOST_STATIC_ASSERT(sizeof(test(dummy<bas, int()>())) == sizeof(false_type)); BOOST_STATIC_ASSERT(sizeof(test(dummy<bax, int()>())) == sizeof(true_type)); Unfortunately it fails (with a compiler error, not with a misleading detection) if a class has a nested result with more than one (non defaulted) argument. I think that Daniel Walker found some tricks plus compier workarounds to overcome this problem for the general MPL_HAS_TEMPLATE_XXX, But even with the plain test, it is not a big stretch to assume that a function object will not have result<> nested template unless it is trying to implement the result protocol. HTH, -- gpd