|
From: mcostalba on 5 May 2008 15:57 On 5 Mag, 15:09, "Roman.Perepeli...(a)gmail.com" <Roman.Perepeli...(a)gmail.com> wrote: > On 1 May, 21:43, mcostalba <mcosta...(a)gmail.com> wrote: > > > I have to detect if a functor type Fun has a given signature Sig, i.e. > > if Fun::operator() has a signature Sig > > Take a look at is_call_possible metafunction, which was discussed > in this group before > (http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/ > thread/4f7c7a96f9afbe44/e5fbc9305539f699#e5fbc9305539f699). > It seems to do what you want. > Thanks Roman for your link. Actually there are some good ideas in that implementation and I will try to borrow a few of them... Unfortunatly it does not fit the bill 100%, indeed: - Implicit argument type conversion should be avoided in my context, due to some ambiguites that can arise when there is more then one candidate among the overload set. So signature matching would be ok to be strict. - It seems you have to add a specialization for each argument arity, in my implementation I would try to avoid this. Indeed my proposed implementation it's already ok at 95%, the only case for which it fails is detecting pointers to CONST operator() members with a given signature. Anyhow, for interested people, many of the ideas, included overloading comma operator template <typename type, typename U> U& operator,(U&, void_exp_result<type>); to workaround void return types are also exposed in "Detecting the Arity of Function Objects" under the link http://boost-sandbox.sourceforge.net/libs/proto/doc/html/boost_proto/appendices/implementation/function_arity.html where an equivalent solution is documented by Eric Nibler in his boost::proto library. Thanks Marco -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: mcostalba on 6 May 2008 03:47 On 6 Mag, 16:21, "Roman.Perepeli...(a)gmail.com" <Roman.Perepeli...(a)gmail.com> wrote: > > > Alexandre Courpron modified is_call_possible to create > is_exact_call_possible. You can find implementation here:http://groups.google.co.uk/group/comp.lang.c++.moderated/browse_threa... I have quickly checked the link and it surely deserves a deeper read when I found a bit of time. Anyhow here is my much simpler solution...so simple that is probably broken in some way, but I cannot find where: /* Check if a function/functor Fun has a given signature Sig */ template<typename Fun, typename Sig> struct is_compatible { typedef typename boost::remove_pointer<Fun>::type F; /* Build pointer_to_member types from the given signature */ typedef typename pointer_to_member<is_function<F>::value, F, Sig>::type ptm; typedef typename pointer_to_member<is_function<F>::value, F, Sig>::const_type ptm_const; /* Check for a function */ template<class U> static yes_type detect(typename enable_if<is_same<U, Sig> >::type*); /* Check for a functor, either const and non-const members are detected */ template<ptm> struct helper; template<ptm_const> struct helper_const; template<class U> static yes_type detect(helper<&U::operator()>*); template<class U> static yes_type detect(helper_const<&U::operator()>*); /* Default */ template<class U> static no_type detect(...); static const bool value = (sizeof(detect<F>(0)) == sizeof(yes_type)); }; Where template pointer_to_member<> is: /* Convert a signature type Sig to a pointer_to_member type */ template<int is_function, typename T, typename Sig> struct pointer_to_member; template<typename T, typename Sig> struct pointer_to_member<1, T, Sig> // filter out function types { typedef int type; typedef int const_type; }; template<typename T, typename R> struct pointer_to_member<0, T, R()> { typedef R(T::* type) (); typedef R(T::* const_type)() const; }; template<typename T, typename R, typename A0> struct pointer_to_member<0, T, R(A0)> { typedef R(T::* type)(A0); typedef R(T::* const_type)(A0) const; }; ...... and so on for each argument arity ........ BTW it seems to work. Thanks Marco -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: dizzy on 7 May 2008 02:04 Hi mcostalba wrote: <snip> > template<class U> static > yes_type detect(helper<&U::operator()>*); > > template<class U> static > yes_type detect(helper_const<&U::operator()>*); Not sure if the previously discussed solutions does support it but this version at least seems to me broken in regard to overloaded operator(). Supose you have a static_visitor functor (a functor with many overloaded operator()(T&) each taking a different T, usually used with a static visitor aproach). It would be nice if is_compatible<> would determine or not if there is a suitable overload for the signature you want. The expression "&U::operator()" would give an amibuity error in case of overloading (which is usually solved either wraping it with a static_cast to the exact function type wanted from the overload set or used as initialization expression for a pointer/reference to function variable). So a solution might be "helper<static_cast<ptm>(&U::operator())>" and something similar for the const version. I'm also a little puzzled that "&U::operator()" does not give compile error in case of not giving a functor to is_compatible<> because I don't think SFINAE helps here, you have an invalid "value expression" not an invalid "type expression", but quite possible I misunderstand this. -- Dizzy [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: Sending a stream of unsigned char's Next: some quirks of Koenig lookup rule? |