compile-time check that a member function exists

Hi,
I'm pretty new to boost. I want to write some code with a compile-time
check whether a member function exists or not. The code below shows
kinda what I need except I'd obviously like to avoid a specialized
template for each class that I use.
Can anybody point me in the right direction?
Thanks,
John
****************************************
#include <iostream>
using namespace std;
struct WithMemberGo
{
void Go() const {cout<<__PRETTY_FUNCTION__<<" going...."<

John Pretz a écrit :
Hi,
I'm pretty new to boost. I want to write some code with a compile-time check whether a member function exists or not. The code below shows kinda what I need except I'd obviously like to avoid a specialized template for each class that I use.
Can anybody point me in the right direction?
Not sure if it exists in boost, but the good old trick using the (...)
operator may be enough.
Like :
typedef char NotFound;
struct Found { char x[2]; };
template

Thank you very much. That worked great. John Joel FALCOU wrote:
John Pretz a écrit :
Hi,
I'm pretty new to boost. I want to write some code with a compile-time check whether a member function exists or not. The code below shows kinda what I need except I'd obviously like to avoid a specialized template for each class that I use.
Can anybody point me in the right direction?
Not sure if it exists in boost, but the good old trick using the (...) operator may be enough. Like :
typedef char NotFound; struct Found { char x[2]; };
template
struct test_for_member_go{ }; template<class T> static Found test_for_go(test_for_member_go *); template<class T> static NotFound test_for_go( ... ); template<class T> struct test { static const bool value = (sizeof( test_for_go<T>( 0 ) ) == sizeof(Found)); typedef boost::mpl::bool_<value> type; };
then test<X>::type should give you a CT boolean that indicates if go is a member of T. This could be easily turned into a macro-like features that can be retargeted for any member with any signature.
-- John Pretz -- P-23, MS H803 Los Alamos National Lab Los Alamos, NM 87545 Phone: (505)665-5847 Fax: (505)665-4121

Le Mar 22 juillet 2008 22:38, John Pretz a écrit :
Thank you very much. That worked great.
It's pretty rough and need to be "standardized" so it actually acts properly as a MPL bool and make it parametrable on the name of the member. I think a macro using BOOST_TYPEOF to get the type of the function pointer from its name should be doable.

2008/7/23 joel falcou
Le Mar 22 juillet 2008 22:38, John Pretz a écrit :
Thank you very much. That worked great.
It's pretty rough and need to be "standardized" so it actually acts properly as a MPL bool and make it parametrable on the name of the member. I think a macro using BOOST_TYPEOF to get the type of the function pointer from its name should be doable.
Could you please elaborate a bit more? I'd like to apply the above test to something like this: template<class Impl> struct my_class { bool f1() { return f1_impl(has_mem_fun_f1<Impl>::type); } bool f2()... bool f3()... //...etc... private: bool f1_impl(mpl::bool_<true>) { return impl_.f1(); } bool f1_impl(mpl::bool_<false>) { return false; } Impl impl_; }; In other words, in this class I want to "convert" static restrictions to dynamic ones, i.e. to return false whenever the interface function is not defined in the implementation. So is it possible to parametrize the above test on the mem.func. name? Thanks!

Igor R a écrit :
2008/7/23 joel falcou
: Le Mar 22 juillet 2008 22:38, John Pretz a écrit :
Thank you very much. That worked great.
It's pretty rough and need to be "standardized" so it actually acts properly as a MPL bool and make it parametrable on the name of the member. I think a macro using BOOST_TYPEOF to get the type of the function pointer from its name should be doable.
Could you please elaborate a bit more?
I'd like to apply the above test to something like this:
template<class Impl> struct my_class { bool f1() { return f1_impl(has_mem_fun_f1<Impl>::type); } bool f2()... bool f3()... //...etc... private: bool f1_impl(mpl::bool_<true>) { return impl_.f1(); } bool f1_impl(mpl::bool_<false>) { return false; } Impl impl_; };
In other words, in this class I want to "convert" static restrictions to dynamic ones, i.e. to return false whenever the interface function is not defined in the implementation. So is it possible to parametrize the above test on the mem.func. name?
Check Boost.vault for a file called introspection.zip, it contains the afformentionned macros in a boost-ified form. -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Check Boost.vault for a file called introspection.zip, it contains the afformentionned macros in a boost-ified form.
Great, thank you! Unfortunately, there's one more issue: it seems that this test fails if the function is inherited from a base class. I mean the following situation: struct B { void f(int); }; struct D : B { }; BOOST_HAS_MEMBER_FUNCTION(f, void(int)) //has_member_function_f<D>::type is mpl::bool_<false> Is it possible to overcome this problem?

Igor R a écrit :
Check Boost.vault for a file called introspection.zip, it contains the afformentionned macros in a boost-ified form.
Great, thank you! Unfortunately, there's one more issue: it seems that this test fails if the function is inherited from a base class. I mean the following situation:
struct B { void f(int); };
struct D : B { };
BOOST_HAS_MEMBER_FUNCTION(f, void(int)) //has_member_function_f<D>::type is mpl::bool_<false>
Is it possible to overcome this problem?
It is a known "bug" (or more precisley a known missing feature). I'm working on a solution but it involves declaring the whole list of a class parent :/ -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Igor R a écrit :
Well, meanwhile, as least in MSVC one can use __if_exists() :)
I just discovered this monster :s Does it work like a type-based #ifdef or what ? Looks fugly to me :/ This whole check-for-a-method process is rather unclear for me. Lots of problem arise with private/protected method/member, and testign for free functions taking type X as a parameters is as ugly too. -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

I just discovered this monster :s Does it work like a type-based #ifdef or what ? Looks fugly to me :/
Yes, it's kind of CT-identifier-based #ifdef. It doesn't checks for signatures or types, it just ensures that the symbol is defined. http://msdn.microsoft.com/en-us/library/x7wy9xh3(VS.80).aspx
participants (5)
-
Igor R
-
joel falcou
-
Joel Falcou
-
Joel FALCOU
-
John Pretz