views:

236

answers:

2

I am trying to specialize some utility code on const member functions, but have problems to get a simple test-case to work.
To simplify the work i am utilizing Boost.FunctionTypes and its components<FunctionType> template - a MPL sequence which should contain the tag const_qualified for const member functions.

But using the test-code below, the specialization on const member functions fails. Does anybody know how to make it work?

The test-code prints out (using VC8 and boost 1.40):

non-const
non-const

Expected output is:

non-const
const

The test-code itself:

#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/mpl/contains.hpp>

namespace ft  = boost::function_types;
namespace mpl = boost::mpl;

template<typename F>
struct select 
{    
    template<bool IsConst /* =false */>
    struct helper {
     static void f() { std::cout << "non-const" << std::endl; } 
    };

    template<>
    struct helper</* IsConst= */ true> {
     static void f() { std::cout << "const" << std::endl; } 
    };

    typedef ft::components<F> components;
    typedef typename mpl::contains<components, ft::const_qualified>::type const_qualified;
    typedef helper<const_qualified::value> result;
};

typedef boost::function<void (void)> Functor;

template<typename MF>
Functor f(MF f)
{
    return boost::bind(&select<MF>::result::f);
}

class C 
{
public:
    void f1() {}
    void f2() const {}
};

int main()
{
    f(&C::f1)(); // prints "non-const" as expected
    f(&C::f2)(); // prints "non-const", expected "const"
}
A: 

I have not tested it, but shouldn't

typedef mpl::contains<components, ft::const_qualified> const_qualified;

be

typedef typename mpl::contains<components::type, ft::const_qualified>::type const_qualified;
leiz
Already tried, doesn't make a difference.
Georg Fritzsche
I saw your edit there, but your components typedef also needs ::type or like I did in the post.
leiz
the ::type is like calling the meta function and getting the result. If you dont do that, it use the meta function itself.
leiz
Also doesn't make a difference.
Georg Fritzsche
+1  A: 

While its still unclear to me why the approach via function_types::components<> doesn't work, i realized that there is a simpler approach with Boost.FunctionTypes to specialize on const member functions:
The classification meta functions like is_member_function_pointer<> optionally take a tag parameter ...

template<typename F>
struct select 
{    
    /* ... helper-struct as before */

    typedef ft::is_member_function_pointer<F, ft::const_qualified> const_qualified;
    typedef helper<const_qualified::value> result;
};
Georg Fritzsche