在业力中使用变量存储容器

时间:2013-12-10 18:15:55

标签: boost-spirit-karma

boost::variant<boost::container::vector<int>, std::string> tmp = "test";
std::string use;
namespace karma = boost::spirit::karma;
bool r = karma::generate(std::back_insert_iterator<std::string>(use), +karma::int_ |   *karma::char_, tmp);

结果是r = false,use =“”。但是,我希望use =“test”。

还有另一个例子

boost::variant<std::vector<int>, std::string> tmp = "test";
std::string use;
namespace karma = boost::spirit::karma;
bool r = karma::generate(std::back_insert_iterator<std::string>(use), +karma::int_ |  +karma::char_, tmp);

结果仍为r = false,use =“”。然而。 怎么了?

1 个答案:

答案 0 :(得分:0)

备用解析器和备用生成器的工作方式之间存在很大差异。替代解析器尝试逐个匹配其操作数,直到其中一个成功。相比之下,替代生成器使用匹配完全您想要生成的属性的操作数,如果没有匹配则不执行任何操作。如果有几个匹配,那么逐个尝试,直到其中一个成功。解决问题的最简单方法是创建karma::rule,以显示变体中的确切属性。

Example on Coliru

#include <iostream>
#include <vector>
#include <boost/spirit/include/karma.hpp>
#include <boost/container/vector.hpp>

int main()
{
    boost::variant<boost::container::vector<int>, std::string> tmp = "test";
    std::string use;
    namespace karma = boost::spirit::karma;
    //Your original code
    bool r = karma::generate(std::back_insert_iterator<std::string>(use), +karma::int_ |   *karma::char_, tmp);
    std::cout << "r=" << std::boolalpha << r << ", Use: \""<< use << '"' << std::endl;

    //Create rules to expose explicitly the attributes you want
    use.clear();
    karma::rule<std::back_insert_iterator<std::string>,boost::container::vector<int>()> ints_rule = karma::int_%',';
    karma::rule<std::back_insert_iterator<std::string>,std::string()> string_rule = *karma::char_;
    r = karma::generate(std::back_insert_iterator<std::string>(use), ints_rule | string_rule, tmp);
    std::cout << "r=" << std::boolalpha << r << ", Use: \""<< use << '"' << std::endl;

    //Same test using ints
    use.clear();
    boost::container::vector<int> tmp_vector;
    tmp_vector.push_back(1);
    tmp_vector.push_back(2);
    tmp=tmp_vector;
    r = karma::generate(std::back_insert_iterator<std::string>(use), ints_rule | string_rule, tmp);
    std::cout << "r=" << std::boolalpha << r << ", Use: \""<< use << '"' << std::endl;

    //An example in which the variant has the exact same attributes exposed by the alternative generator
    use.clear();
    boost::variant<std::vector<int>, std::vector<char> > tmp2;
    std::vector<char> string;
    string.push_back('t');
    string.push_back('e');
    string.push_back('s');
    string.push_back('t');
    tmp2=string;
    r = karma::generate(std::back_insert_iterator<std::string>(use), karma::int_%',' | *karma::char_,tmp2);
    std::cout << "r=" << std::boolalpha << r << ", Use: \""<< use << '"' << std::endl;
}