c++boostboost-mpl

MPL Map Instantiate Type


I have the following:

class Message
{
public:
    bool process()
    {
        return doProcess();
    }
protected:
    virtual bool doProcess() = 0;
};

class Hello : public Message
{
protected:
    bool doProcess()
    {
        return false;
    }
};
typedef typename boost::mpl::map< boost::mpl::pair< boost::mpl::int_< 0 >, Hello > > map;

struct Generator
{
    typedef void result_type;
    template< typename t_type >
    void operator()(std::vector< boost::shared_ptr< Message > >& processors,
                    t_type p_element)
    {
        typedef typename boost::mpl::at< map, t_type >::type c_instanceType
        boost::shared_ptr< Message > temp(reinterpret_cast< Message* >(new c_instanceType));
        p_processors[p_element] = temp;
    }
};

This is then invoke like so:

class MessageProcessor
{
public:
    MessageProcessor() :
        m_processors(12)
    {
        // eventually there will be 12 different messages so I will add
        // them to the mpl map and adjust the range
        boost::mpl::for_each< boost::mpl::range_c< boost::uint8_t, 0, 1 > >
        (
            boost::bind(Generator(), boost::ref(m_processors), _1)
    }
private: 
    std::vector< boost::shared_ptr< Message > > m_processors;
};

This code compiles cleanly; however, when the function is later invoked like so:

m_processors[0]->process();

A segmenation fault occurs on the line in the process function that returns do process. I am working in gcc 4.8 with boost version 1.55. Also note this isn't the entire code. When walking through with the debugger I see that the vptr appears to be null when invoking the doProcess, so the child class doesn't seem to exist. Any ideas on how to fix this?


Solution

  • So the issue appears to be that the type is not actually found when doing at<> and something else is being returned instead of the Hello type. It looks like the type that is passed in by boost::for_each is of type, boost::mpl::integral_c<boost::uint8_t, 0> which doesn't exist in the mpl map since I am storing boost::mpl::int_<0> as the key. Changing the key type in the map to boost::mpl::integeral_c< boost::uint8_t, 0 > does not segfault and performs as expected.