c++ - 如何将 boost visitor 概念与包含状态变量的类一起使用?

标签 c++ boost visitor-pattern boost-variant

我正在尝试使用 boost::static_visitor 对影响某些变量状态的 boost::variant 类型执行操作。我的方法是在我的命令访问者类中包含所有状态变量,但似乎这是不可能的。

这是我的代码示例:

#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;
}

我希望这段代码能够理解我要完成的任务的要点。但是,它不会编译,并给出 [paraphrased] 错误:

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 修饰符必须放在 operator() 函数原型(prototype)的末尾,这使得编译器认为成员变量不能被函数修改。

我的问题是:

使用必须在访问之间保持状态的变量来完成访问者模式(使用 boost::variant)的正确方法是什么?

最佳答案

有几个错别字,但我做了几个模组,现在可以用了。本质上,您的 static_visitor 类在每次访问时都会发生变异,因此 operator() 方法不能是常量。

#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

关于c++ - 如何将 boost visitor 概念与包含状态变量的类一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23432606/

相关文章:

c++ - Win32Api - 窗口名称属性

c++ - 我如何在 Boost ASIO 中获得等待 async_read_some 的函数?

c++ - 使用 runge_kutta4 的高维数组

java - List.of() 在访问者模式中的用法

java - 如何确定 Eclipse JDT 中方法或字段的修饰符?

c++ - 如何在 Linux 中查询 Vsync 阶段

c++ - 使用递归函数时出现段错误

具有通用返回类型的访问者模式的 Java/Kotlin 强制转换异常

c++ - boost::Program_options 一种判断值是来自命令行还是 ini 文件的方法?

c++ - Boost_program_option 链接器错误甚至存在 "boost_program_options"