我如何使用含有状态变量的类升压游客概念? [英] How can I use the boost visitor concept with a class containing state variables?

查看:173
本文介绍了我如何使用含有状态变量的类升压游客概念?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用boost :: static_visitor实现对影响某些变量的状态一个boost :: variant类型的行动。我的方法是包含所有在我的命令访问类的状态变量,但似乎这是不可能的。

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.

下面是我的code例如:

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;
             ^

我假定这个错误是由于const修饰必须放置在操作者()函数原型这使得编译器的端认为成员变量不能由函数修改

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.

我的问题是这样的:

什么是实现访问者模式的正确方法(使用boost ::变量)与必须保持互访的状态变量?

推荐答案

有一对夫妇错别字,但我做了几MODS和现在的工作。基本上你static_visitor类是本身变异每次访问,使操作者()方法不能是const。

There were a couple of typos, but I made a few mods and it works now. Essentially your static_visitor class is mutating itself on each visit, so the operator() methods can't be const.

#include <string>
#include <sstream>
#include <vector>
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
#include <iostream>


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)
{
   m_runningSum += t.varA;
   m_outStream << "TYPEA ACTION: " << t.varB << std::endl;
}

void operator()(TypeB & t)
{
   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 m_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;
}

http://www.compileonline.com/compile_cpp11_online.php 运行提供了:

Compiling the source code....
$g++ -std=c++11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1

Executing the program....
$demo 
Result:
TYPEA ACTION: 2
String2 ACTION String1

这篇关于我如何使用含有状态变量的类升压游客概念?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆