Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost variant visitor with an extra parameter

I have code that resembles below.

typedef uint32_t IntType;
typedef IntType IntValue;
typedef boost::variant<IntValue, std::string>  MsgValue;

MsgValue v;

Instead of saying this,

IntValue value = boost::apply_visitor(d_string_int_visitor(), v);

I would like to pass an extra parameter like this: But operator() gives a compile error.

//This gives an error since the overload below doesn't work.
IntValue value = boost::apply_visitor(d_string_int_visitor(), v, anotherStr);

class d_string_int_visitor : public boost::static_visitor<IntType>
{
public:
    inline IntType operator()(IntType i) const
    {
        return i;
    }

    inline IntValue operator()(const std::string& str) const noexcept
    {
        // code in here
    }

    //I want this, but compiler error.
    inline IntValue operator()(const std::string& str, const std::string s) const noexcept
    {
        // code in here
    }
};
like image 630
Ivan Avatar asked Apr 14 '15 03:04

Ivan


1 Answers

You can bind the extra string argument to the visitor using std::bind. First, add the std::string parameter to all of the visitor's operator() overloads.

class d_string_int_visitor : public boost::static_visitor<IntType>
{
public:
    inline IntType operator()(IntType i, const std::string& s) const
    {
        return i;
    }

    inline IntValue operator()(const std::string& str, const std::string& s) const noexcept
    {
        // code in here
        return 0;
    }
};

Now create a visitor to which you have bound the second string argument.

auto bound_visitor = std::bind(d_string_int_visitor(), std::placeholders::_1, "Hello World!");
boost::apply_visitor(bound_visitor, v);

Live demo

However, a better solution would be to pass the string as the visitor's constructor argument.

like image 152
Praetorian Avatar answered Sep 26 '22 10:09

Praetorian