我有一个以下问题:我正在重用使用real_p解析器解析实数的旧代码。我想捕获每个数字,将其转换为字符串,并将其放在字符串向量中。 我使用以下代码,其中l_double是double类型的变量,convertdouble函数将double转换为字符串,result.m_literalValues是字符串的向量。 但是,代码不会将解析后的值分配给l_double。
rule<> alternative3 = +(real_p [assign_a(l_double)]
[push_back_a(result.m_LiteralValues, convertdouble(l_double))]
>> str_p(",")
)
有谁知道我做错了什么?
注意:我不会重新设计旧代码,这比给出的示例复杂得多。我只想提取解析的所有值的字符串,并将它们放在字符串向量中。
答案 0 :(得分:1)
问题似乎位于push_back_a(result.m_LiteralValues, convertdouble(l_double))
,特别是convertdouble(l_double)
。 push_back_a
requires它的第二个参数是存储在“策略持有者actor”中的引用,因此使用函数调用会导致错误。如果你不需要存储l_double
而只是简单地使用它,那么实现你想要的一种方法是创建你自己的凤凰函数,其行为类似于push_back_a
所解释{{3} }(完整示例here)。
你可以像这样定义凤凰函数:
struct push_back_impl
{
template <typename Container, typename Item>
struct result
{
typedef void type;
};
template <typename Container, typename Item>
void operator()(Container& c, Item const& item) const
{
c.push_back(convertdouble(item));
}
};
function<push_back_impl> const push_back = push_back_impl();
然后像这样定义你的规则:
rule<> alternative3 = +( real_p[push_back(var(result.m_LiteralValues),arg1)] >> str_p(",") );
完全可编辑的代码(如果您不能/不想使用c ++ 11,请更改for循环以显示结果):
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_operators.hpp>
#include <boost/spirit/include/phoenix1_functions.hpp>
#include <boost/spirit/include/phoenix1_primitives.hpp>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace boost::spirit::classic;
using namespace phoenix;
std::string convertdouble(const double& d)
{
std::stringstream ss;
ss<<d;
return ss.str();
}
struct push_back_impl
{
template <typename Container, typename Item>
struct result
{
typedef void type;
};
template <typename Container, typename Item>
void operator()(Container& c, Item const& item) const
{
c.push_back(convertdouble(item));
}
};
function<push_back_impl> const push_back = push_back_impl();
struct Results
{
std::vector<std::string> m_LiteralValues;
};
int main()
{
Results result;
char const* test="2.5,3.6,4.8,";
rule<> alternative3 = +( real_p[push_back(var(result.m_LiteralValues),arg1)] >> str_p(",") );
if(parse(test,alternative3,space_p).full)
{
std::cout << "success" << std::endl;
for(auto& str :result.m_LiteralValues)
std::cout << str << std::endl;
}
else
{
std::cout << "failure" << std::endl;
}
return 0;
}