Using SFINAE to detect presence of member function - Unreliable
I have taken a look at anything I could find through Boost lists and Google that came up as
a solution to the problem of detecting the existence of a member function in
a type... using SFINAE.
All of them have one problem.. they are unable to detect the existence of
the member function if it was defined in a base class. They can only detect
if the member function was directly defined in the class being tested.
At their heart, all solutions boil down to some variation of the following
template class with a template parameter that is a (non-type) pointer to
member function:
template
2009/1/30 Naik, Roshan
I have taken a look at anything I could find through Boost lists and Google that came up as a solution to the problem of detecting the existence of a member function in a type... using SFINAE.
<cut> Maybe this one does what you need: http://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/threa... HTH, Roman Perepelitsa.
Maybe this one does what you need: http://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/threa...
HTH, Roman Perepelitsa.
Thanks Roman. It is kind of amazing! Both has_member<> and is_call_possible<> are very interesting (even if a bit ugly). But is_call_possible doesn't seem to work for member functions that don't have any arguments. I tried twiddling with the implementation a bit and no luck yet. -Roshan
2009/1/31 Naik, Roshan
Maybe this one does what you need:
http://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/threa...
Thanks Roman. It is kind of amazing! Both has_member<> and is_call_possible<> are very interesting (even if a bit ugly).
But is_call_possible doesn't seem to work for member functions that don't have any arguments. I tried twiddling with the implementation a bit and no luck yet.
Sorry, I don't know how to make it work for functions without arguments. Problem is that this program is invalid: void foo() {} void foo(...) {} int main() { foo(); // Ambiguous. } Roman Perepelitsa.
Seems like the following specialization of impl<> works:
template <typename r>
struct impl
Maybe this one does what you need: http://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/threa...
Thanks Roman. It is kind of amazing! Both has_member<> and is_call_possible<> are very interesting (even if a bit ugly). But is_call_possible doesn't seem to work for member functions that don't have any arguments. I tried twiddling with the implementation a bit and no luck yet. Sorry, I don't know how to make it work for functions without arguments. Problem is that this program is invalid: void foo() {} void foo(...) {} int main() { foo(); // Ambiguous. } Roman Perepelitsa.
2009/2/2 Naik, Roshan
Seems like the following specialization of impl<> works:
template <typename r>
struct impl
{
static const bool value =
sizeof(
return_value_check
::deduce( ( (((derived_type*)0)->operator()(), details::void_exp_result<type>())
) )
) == sizeof(yes);
};
I don't think it does. Try this test:
struct foo {
void operator()() const {}
};
int main() {
is_call_possible
Roman Perepelitsa wrote:
Sorry, I don't know how to make it work for functions without arguments. Problem is that this program is invalid: void foo() {} void foo(...) {}
int main() { foo(); // Ambiguous. }
Since the stuff now works with void arguments (as I noted).. only one final issue remains... This does not work with types that cannot be used as base classes (e.g. primitive types, enums) etc. The compiler errors out. -Roshan
Naik, Roshan a écrit :
So .. my question is ....does anyone have solution that works for the case when the method is defined in the base class too ?
I am thinking ... if it is possible to extract the class name from the actual type of &Derived::foo, then the problem can be solved... but the type extraction mechanism must not error out on types that have absolutley no member function called foo.
I stumbled across this problem recently. My only fix that still need to be added to my introspection prototype is to have a HAS_INHERITED_MEMBER_FUNCTION( method, prototype, (list)(of)(base)(class)(as)(a)(PP_Sequence)); that do a compound check on a given type to see if T::method or any (base class)::method exists, performing a or_ on the result. eg : class Base1 { void foo(int); }; class Base2; class Foo : public Base1, public Base2 {}; HAS_INHERITED_MEMBER_FUNCTION(foo, void(int), (Base1)(Base2) ); in which : has_inherited_member_function<Foo>::value will return true. It's cumbersome has the base classes of Foo need to be explicited in the macro. Retrieving the base class from the derived type seems quite hard though and I really do'nt see hwo you can do it. -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35
participants (3)
-
Joel Falcou
-
Naik, Roshan
-
Roman Perepelitsa