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 =“”。然而。 怎么了?
答案 0 :(得分:0)
备用解析器和备用生成器的工作方式之间存在很大差异。替代解析器尝试逐个匹配其操作数,直到其中一个成功。相比之下,替代生成器使用匹配完全您想要生成的属性的操作数,如果没有匹配则不执行任何操作。如果有几个匹配,那么逐个尝试,直到其中一个成功。解决问题的最简单方法是创建karma::rule
,以显示变体中的确切属性。
#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;
}