|
Boost Users : |
Subject: Re: [Boost-users] [Function] requiring an exact match in function signature?
From: Mathias Gaunard (mathias.gaunard_at_[hidden])
Date: 2010-04-03 15:51:48
Nathan Ridge a écrit :
>> Anyway, if you want to test the signature of a function object, just
>> take the address of &T::operator() and check it is what you want. Of
>> course that won't work if it's a template or if it is overloaded.
>
> Could you be kind enough to give an example of how I can do such a check?
This works on GCC, haven't tested with other compilers.
#include <boost/mpl/bool.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/member_function_pointer.hpp>
#include <boost/function_types/property_tags.hpp>
template<class X, class Prototype> struct function_to_member
{
typedef typename
boost::function_types::result_type<Prototype>::type result;
typedef typename
boost::function_types::parameter_types<Prototype>::type args;
typedef typename boost::mpl::push_front<args, X*>::type
base;
typedef typename boost::mpl::push_front<base, result>::type
type;
};
template<class X, class Prototype> struct build_member_type
{
typedef typename function_to_member<X,Prototype>::type
root;
typedef typename
boost::function_types::member_function_pointer<root>::type type;
};
template<class X, class Prototype> struct build_const_member_type
{
typedef typename function_to_member<X,Prototype>::type root;
typedef typename boost::function_types::member_function_pointer<
root,
boost::function_types::const_qualified
>::type type;
};
template<class T, typename Sig>
struct has_signature
{
typedef char not_found;
struct found { char x[2]; };
template<typename X, typename build_member_type<X, Sig>::type>
struct member {};
template<typename X, typename build_const_member_type<X, Sig>::type>
struct const_member {};
template<typename X> static found test(member<X, &X::operator()>*);
template<typename X> static found test(const_member<X,
&X::operator()>*);
template<typename X> static not_found test(...);
static const bool value = (sizeof(found) == sizeof(test<T>(0)));
typedef boost::mpl::bool_<value> type;
};
example of use:
struct foo { int operator()(short) const; };
struct bar { int operator()(short); };
struct baz { int operator()(int); };
int main()
{
std::cout << has_signature<foo, int(short)>::value << std::endl; // 1
std::cout << has_signature<bar, int(short)>::value << std::endl; // 1
std::cout << has_signature<baz, int(short)>::value << std::endl; // 0
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net