|
Boost : |
From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2002-11-12 04:26:52
Douglas Gregor wrote:
> On Monday 11 November 2002 04:56 am, Aleksey Gurtovoy wrote:
> [snip my limited example]
> > Hmm, interesting, so if this actually worked, we would be happy:
> >
> [snip nifty-looking is_callable implementation]
> >
> > ?
>
> Well, you need to do some trickery to make it work when R=void,
> but otherwise I think we would be _very_ happy if this worked. Is
> there a tweak to the core language that would guarantee such a thing?
>
Well, since that particular reason of type deduction failure (attempting to
call a member function on the object which type does not contain the
specified member) is not explicitly listed under 14.8.2 para 2, yes, in one
or another form. I haven't figured out yet what would be the best way
(politically and technically) to get that part of the language into the
state we would like it to have ;).
Hmm, actually, this one is _already_ required to work:
#include "boost/mpl/bool_c.hpp"
#include "boost/mpl/logical/and.hpp"
#include "boost/type_traits/is_class.hpp"
#include "boost/static_assert.hpp"
namespace mpl = boost::mpl;
typedef char (&no_tag)[1];
typedef char (&yes_tag)[2];
template< long > struct sink {};
template<typename T> T get();
template< typename Functor, typename R, typename T1 >
no_tag has_call_operator_tester(...);
template< typename Functor, typename R, typename T1 >
yes_tag is_callable_helper(
sink< sizeof(static_cast<R>(
get<Functor>().Functor::operator()( get<T1>() ) // here
))>
);
template<
typename Functor, typename R, typename T1
>
struct has_function_call_operator
: mpl::bool_c<
sizeof(has_call_operator_tester<Functor,R,T1>(
sink<sizeof(R)>()
))
== sizeof(yes_tag)
>
{
};
template<
typename Functor, typename R, typename T1
>
struct is_callable
: mpl::logical_and<
boost::is_class<Functor>
, has_function_call_operator<Functor,R,T1>
>
{
};
struct her {};
struct my { int operator()(int); };
BOOST_STATIC_ASSERT((!is_callable<int,int,int>::value));
BOOST_STATIC_ASSERT((!is_callable<her,int,int>::value));
BOOST_STATIC_ASSERT((is_callable<my,int,int>::value));
The marked line falls directly under one of the 14.8.2 para 2's items:
"-- Attempting to use a type in the qualifier portion of a qualified name
that names a type when that
type does not contain the specified member [...]"
So getting 'is_callable' might be as easy as filing a bug report to your
favorite vendor(s) (and following it up until it's fixed, of course :).
Aleksey
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk