I'm attempting to use boost::static_visitor to implement actions on a boost::variant type that affect the state of some variable. My approach was to contain all of the state variables in my command visitor class, but it seems this is not possible.
Here is my code example:
#include <string>
#include <sstream>
#include <vector>
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
struct TypeA
{
int varA;
int varB;
};
struct TypeB
{
std::string varA;
std::string varB;
};
typedef boost::variant<TypeA, TypeB> MyVariantType;
class MyCommandVisitor : public boost::static_visitor<>
{
public:
//These are just examples, the actions only need to be able to touch
// internal variables.
void operator()(TypeA & t) const
{
m_runningSum += t.varA;
m_outStream << "TYPEA ACTION: " << t.varB << std::endl;
}
void operator(TypeB & t) const
{
m_charCount += t.varA.size();
m_outStream << t.varB << " ACTION " << t.varA << std::endl;
}
std::string emitWork(std::vector<MyVariantType> listOfVariants)
{
m_outStream.clear();
m_runningSum = 0;
m_charCount = 0;
BOOST_FOREACH(MyVariantType & v, listOfVariants)
{
boost::apply_visitor(*this, v);
}
return m_outStream.str();
}
protected:
int m_runningSum;
int m_charCount;
std::stringstream outStream;
}; //End class MyCommandVisitor
int main(int argc, char **argv)
{
TypeA ta;
ta.varA = 1;
ta.varB = 2;
TypeB tb;
tb.varA = "String1";
tb.varB = "String2";
std::vector<MyVariantType> listOfWork;
listOfWork.push_back(ta);
listOfWork.push_back(tb);
MyCommandVisitor myCV;
std::string result = myCV.emitWork(listOfWork);
std::cout << "Result:\n" << result << std::endl << std::endl;
return 0;
}
I hope this snippet gets across the gist of what I'm trying to accomplish. It won't compile, however, giving the [paraphrased] error:
error: no operator "<<" matches these operands
operand types are: const std::stringstream << const char [N]
m_outStream << "TYPE A ACTION: " << t.varB << std::endl;
^
I'm assuming this error is due to the const modifier that must be placed on the end of the operator() function prototype which makes the compiler believe that member variables cannot be modified by the function.
My question is thus:
What is the proper way to accomplish the visitor pattern (using boost::variant) with variables that must maintain state between visits?