views:

103

answers:

1

I have a class that accepts a list of policy classes using boost::mpl. Each policy class contains an identifying tag. I would like MyClass to produce the OR-ed result of each policy class' identifying tag. Unfortunately, I'm having some trouble figuring out how to correctly use the boost::mpl::fold<> functionality. If anybody can help, I would appreciate it.

#include <boost/mpl/vector.hpp>
#include <boost/mpl/bitor.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>

namespace bmpl = boost::mpl;

template< class ListOfPolicies >
class CMyClass : public bmpl::inherit_linearly< ListOfPolicies, bmpl::inherit< bmpl::_1, bmpl::_2 > >::type
{
public:
    int identifier() const
    {
        // error C2039: 'tag' : is not a member of 'PolicyA'
        return bmpl::fold< ListOfPolicies, bmpl::int_< 0 >, bmpl::bitor_< bmpl::_1, bmpl::_2 > >::value
    }
};

template< class T >
class PolicyA
{
public:
    enum { MY_IDENTIFIER = 0x00000001 };
};

class PolicyB
{
public:
    enum { MY_IDENTIFIER = 0x00000010 };       
};

int _tmain(int argc, _TCHAR* argv[])
{       
    CMyClass< PolicyA, PolicyAB > AB
    assert( AB.identifier() == ( PolicyA::MY_IDENTIFIER | PolicyB::MY_IDENTIFIER ));
    return 0;
}

Thanks, PaulH

+1  A: 

I haven't explicitly tested if it does what you intend to (aside from not getting the assert), but as fold returns a type containing a value, the line giving you an error should be:

return bmpl::fold< ListOfPolicies, 
                   bmpl::int_<0>, 
                   bmpl::bitor_<bmpl::_1, bmpl::_2> 
                 >::type::value;

Aside from that, bitor expects its arguments to be an integral constant (doc):

class PolicyA
{
public:
    typedef boost::mpl::integral_c_tag tag;
    typedef int value_type;
    enum { value = 0x00000001 };
};

Continuing, fold works on mpl::vectors, thus you need a change in main:

CMyClass< boost::mpl::vector<PolicyA, PolicyB> > AB;

You also can't just hand an undefined type as a template parameter - thus i had to make PolicyA a non-template class. You'll have to see how to get working what you originally intended there.

Georg Fritzsche
I understand now. Thanks for your help.
PaulH