boost::spirit::字符串的业力输出(引号)

boost::spirit::字符串的业力输出(引号),boost,boost-spirit,boost-variant,boost-spirit-karma,Boost,Boost Spirit,Boost Variant,Boost Spirit Karma,我试图用boost::spirit::karma来摆脱引号中的字符串。如果它只是一个字符串,那么它就可以正常工作。但是,对于std::vector中boost::variant中的字符串,它不是。不过,仅仅打印字符串就行了,我不太明白为什么 第(1)行工作正常,但不符合我的要求。第(2)行应该这样做,但没有 #include <iostream> #include <string> #include <boost/variant.hpp> #include &

我试图用boost::spirit::karma来摆脱引号中的字符串。如果它只是一个字符串,那么它就可以正常工作。但是,对于std::vector中boost::variant中的字符串,它不是。不过,仅仅打印字符串就行了,我不太明白为什么

第(1)行工作正常,但不符合我的要求。第(2)行应该这样做,但没有

#include <iostream>
#include <string>
#include <boost/variant.hpp>
#include <boost/spirit/include/karma.hpp>
namespace karma = boost::spirit::karma;

typedef std::vector<boost::variant<int, std::string>> ParameterList;
typedef boost::variant<int, std::string, ParameterList> Parameter;

main()
{
    using karma::int_;
    using boost::spirit::ascii::string;
    using karma::eol;
    using karma::lit;

    std::string generated;
    std::back_insert_iterator<std::string> sink(generated);

    // (1)
    karma::rule<std::back_insert_iterator<std::string>, ParameterList()> parameterListRule = (int_ | string) % lit(", "); // This works!

    // (2)
    //karma::rule<std::back_insert_iterator<std::string>, ParameterList()> parameterListRule = (int_ | (lit('"') << string << lit('"'))) % lit(", "); // This does not work

    karma::rule<std::back_insert_iterator<std::string>, Parameter()> parameterRule = (int_ | (lit('"') << string << lit('"')) | parameterListRule) << eol; // This does work, even though it also escapes the string in a pair of quotation marks

    karma::generate(sink, parameterRule, 1); // Works
    karma::generate(sink, parameterRule, "foo"); // Works
    karma::generate(sink, parameterRule, Parameter(ParameterList{1, "foo"})); // Only works using rule (1), not with (2)
    std::cout << generated;
}
#包括
#包括
#包括
#包括
名称空间业力=提升::精神::业力;
typedef std::向量参数列表;
typedef boost::变量参数;
main()
{
使用因果报应::int;
使用boost::spirit::ascii::string;
使用karma::eol;
使用业力:点燃;
std::生成的字符串;
std::back\u insert\u迭代器接收器(已生成);
// (1)
karma::rule parameterListRule=(int|string)%lit(“,”)//这很有效!
// (2)

//karma::rule parameterListRule=(int_124;(lit(“”)如果迭代数据类型,则应迭代规则

#include <iostream>
#include <string>
#include <boost/variant.hpp>
#include <boost/spirit/include/karma.hpp>
namespace karma = boost::spirit::karma;

typedef boost::variant<int, std::string> Item;
typedef std::vector<Item> ParameterList;
typedef boost::variant<int, std::string, ParameterList> Parameter;

int main()
{
  using karma::int_;
  using boost::spirit::ascii::string;
  using karma::eol;
  using karma::lit;

  std::string generated;
  std::back_insert_iterator<std::string> sink(generated);

  karma::rule<std::back_insert_iterator<std::string>, Item()> itemRule =
      int_ | (lit('"') << string << lit('"'));

  karma::rule<std::back_insert_iterator<std::string>, ParameterList()>
    parameterListRule =  itemRule % lit(", ");

  karma::rule<std::back_insert_iterator<std::string>, Parameter()>
    parameterRule = (int_ | (lit('"') << string << lit('"')) | parameterListRule) << eol;

  karma::generate(sink, parameterRule, 1);
  karma::generate(sink, parameterRule, "foo");
  karma::generate(sink, parameterRule, Parameter(ParameterList {1, "foo"}));
  std::cout << generated;

  return 0;
}
#包括
#包括
#包括
#包括
名称空间业力=提升::精神::业力;
typedef boost::变量项;
typedef std::向量参数列表;
typedef boost::变量参数;
int main()
{
使用因果报应::int;
使用boost::spirit::ascii::string;
使用karma::eol;
使用业力:点燃;
std::生成的字符串;
std::back\u insert\u迭代器接收器(已生成);
因果报应::规则项规则=
int_124;(亮(“”)
编辑如果递归不是目标,这里有一个编辑版本可以解决问题和转义:(或)

嗯。看起来你可能在寻找一个递归属性/规则:

typedef boost::make_recursive_variant<int, std::string, std::vector<boost::recursive_variant_> >::type Parameter;
现在,您的标题建议包含双引号的字符串应该转义这些

str = '"' << *('\\' << char_('"') | char_) << '"';
gen = int_ | str | gen % ", ";
如果递归确实是一种功能,您可能希望看到嵌套参数列表的分组:

包含 #包括 #包括 使用名称空间boost; void foo(字符*缓冲区,uint32\u t lhOid){ boost::spirit::karma::generate(缓冲区,boost::spirit::right_align(20)[boost::spirit::karma::int_],lhOid); *缓冲区='\0'; } int main(){ char-arr[21]; foo(arr,1234);
std::cout.write(arr,21)我很高兴您找到了它。:(为了完整性,添加了一个简化规则、修复引用但不改变属性结构的解决方案)谢谢,我没有尝试递归地定义它,应该清楚地说明这一点。你的解决方案非常好,并且解决了它。我标记了Mike_M的,因为它准确地指出了问题,并且没有引入递归。但是我仍然不明白为什么添加引号会使代码不起作用。这正好解决了它。一个y关于第(1)行工作原因和第(2)行的解释没有?对不起,没有。从构图本身来看,人们可能会想到,但是似乎karma在转发属性时遇到了一些问题,尽管
karma::lit
没有暴露任何问题。但是我在这里不是专家,也许@sehe知道更多。但是你可以很快学会解决这些问题;-)
str = '"' << *('\\' << char_('"') | char_) << '"';
gen = int_ | str | gen % ", ";
for (Parameter p : Parameters { 
        1, 
        "foo",
        Parameters { 1, "foo" },
        Parameters { 1, "escape: \"foo\"", Parameters { "2", "bar" } } 
   })
{
    std::cout << karma::format(gen, p) << '\n';
}
1
"foo"
1, "foo"
1, "escape: \"foo\"", "2", "bar"
1
"foo"
{1, "foo"}
{1, "escape: \"foo\"", {"2", "bar"}}
#include <boost/variant.hpp>
#include <boost/spirit/include/karma.hpp>

namespace karma = boost::spirit::karma;
typedef boost::make_recursive_variant<int, std::string, std::vector<boost::recursive_variant_> >::type Parameter;
typedef std::vector<Parameter> Parameters;

int main()
{
    typedef boost::spirit::ostream_iterator It;

    karma::rule<It, Parameter()>   gen;
    karma::rule<It, std::string()> str;

    str = '"' << *('\\' << karma::char_('"') | karma::char_) << '"';
    gen = (karma::int_ | str | '{' << gen % ", " << '}');

    for (Parameter p : Parameters { 
            1, 
            "foo",
            Parameters { 1, "foo" },
            Parameters { 1, "escape: \"foo\"", Parameters { "2", "bar" } } 
       })
    {
        std::cout << karma::format(gen, p) << '\n';
    }
}
#include <iostream>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/karma_right_alignment.hpp>

using namespace boost;

void foo(char* buffer, uint32_t lhOid) {
    boost::spirit::karma::generate(buffer, boost::spirit::right_align(20)[boost::spirit::karma::int_], lhOid);
    *buffer = '\0';
}

int main() {
    char arr[21];
    foo(arr, 1234);
    std::cout.write(arr, 21) << std::endl;
    return 0;
}