Boost spirit 解析器因类型不完整错误而失败
Boost spirit parser fails with incomplete type error
我一直在尝试各种方法,但仍然不太理解为什么以下操作失败并显示 'incomplete type' 错误
#define BOOST_PHOENIX_LIMIT 30
#define SPIRIT_ARGUMENTS_LIMIT 30
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <ctime>
#include <chrono>
#include <string>
#include <iomanip>
namespace qi = boost::spirit::qi;
namespace phi = boost::phoenix;
using namespace std::chrono_literals;
using namespace qi::labels;
using It = std::string::const_iterator;
#define PRICE_MULT 10000
class ImbalanceMsg
{
public:
ImbalanceMsg(){}
ImbalanceMsg(timespec ts,
uint8_t msgtype,
uint64_t seq_num,
std::string symbol,
uint64_t symbol_seqnum,
uint64_t ref_price,
uint32_t paired_qty,
uint32_t total_imb_qty,
uint32_t mkt_imb_qty,
uint32_t auction_time,
char auction_type,
char imb_side,
uint64_t cont_clear_price,
uint64_t auction_int_clear_price,
uint64_t ssr_filling_price,
uint64_t ind_match_price,
uint64_t upper_collar,
uint64_t lower_collar,
uint32_t auction_status,
uint32_t freeze_status,
uint32_t num_ext
) :
m_ref_price{ref_price},
m_paired_qty{paired_qty},
m_total_imb_qty{total_imb_qty},
m_mkt_imb_qty{mkt_imb_qty},
m_auction_time{auction_time},
m_auction_type{auction_type},
m_imb_side{imb_side},
m_cont_clear_price{cont_clear_price},
m_auction_int_clear_price{auction_int_clear_price},
m_ssr_filling_price{ssr_filling_price},
m_ind_match_price{ind_match_price},
m_upper_collar{upper_collar},
m_lower_collar{lower_collar},
m_auction_status{auction_status},
m_freeze_status{freeze_status},
m_num_ext{num_ext}
{}
// auto msg = parse( "105,42982201,15:00:05.553620224,AAPL,1192101,157.56,0,200,0,1600,C,S,0,0,0,157.57,159140000,155980000,0,0,0" );
std::string m_symbol;
uint64_t m_symbol_seqnum;
uint64_t m_ref_price;
uint32_t m_paired_qty;
uint32_t m_total_imb_qty;
uint32_t m_mkt_imb_qty;
uint32_t m_auction_time;
char m_auction_type;
char m_imb_side;
uint64_t m_cont_clear_price;
uint64_t m_auction_int_clear_price;
uint64_t m_ssr_filling_price;
uint64_t m_ind_match_price;
uint64_t m_upper_collar;
uint64_t m_lower_collar;
uint32_t m_auction_status;
uint32_t m_freeze_status;
uint32_t m_num_ext;
};
int main() {
std::string s = "AAPL,1192101,157.56,0,200,0,1600,C,S,0,0,0,157.57,159140000,155980000,0,0,0";
timespec ts;
uint8_t msgtype = 105;
uint64_t seq_num = 42982201;
qi::uint_parser<uint32_t, 10, 1, 6> int_part;
qi::uint_parser<uint8_t , 10, 1, 1> m_digit;
qi::rule<std::string::iterator, uint64_t()>
m_fixed_point = int_part[qi::_val = qi::_1 * PRICE_MULT] >>
-("." >> -(m_digit[qi::_val += qi::_1 * 1000])
>> -(m_digit[qi::_val += qi::_1 * 100])
>> -(m_digit[qi::_val += qi::_1 * 10])
>> -(m_digit[qi::_val += qi::_1 ])
);
qi::rule<std::string::iterator, ImbalanceMsg()>
m_wire_msg = ( qi::as_string[*qi::alpha] >> "," // symbol
>> qi::ulong_ >> "," // symbol seq num
>> m_fixed_point >> "," // ref price
>> qi::uint_ >> "," // paired_qty
>> qi::uint_ >> "," // total_imb_qty
>> qi::uint_ >> "," // mkt_imb_qty
>> qi::uint_ >> "," // auction_time
>> qi::char_ >> "," // auction type
>> qi::char_ >> "," // imb side
>> m_fixed_point >> "," // cont_clear_price
>> m_fixed_point >> "," // auction_int_clear_price
>> m_fixed_point >> "," // ssr_filling_price
>> m_fixed_point >> "," // ind_match_price
>> m_fixed_point >> "," // upper_collar
>> m_fixed_point >> "," // lower_collar
>> qi::ushort_ >> "," // auction status
>> qi::ushort_ >> "," // freeze status
>> qi::ushort_
)[qi::_val = phi::construct<ImbalanceMsg>(ts, msgtype, seq_num,
qi::_1, //symbol
qi::_2, //market_id
qi::_3, //system_id
qi::_4, //exchange_code
qi::_5, //security_type
qi::_6, //lot_size
qi::_7, // prev_close_price
qi::_8, // prev_close_volume
qi::_9, // price_resolution
qi::_10, // round_lot
qi::_11, // mpv
qi::_12,
qi::_13,
qi::_14,
qi::_15,
qi::_16,
qi::_17,
qi::_18
)];
ImbalanceMsg m;
bool ok = parse( s.begin(), s.end(), m_wire_msg, m );
std::cout << "ok=" << ok << std::endl;
}
与 ImbalanceMsg 相比,我没有遇到属性较少的较小 类 的相同问题。
我还有其他几种类型的消息 类,它们的代码相似,但都可以正常编译。
有人可以指点一下吗?
只要有一个占位符就可以编译语义动作表达式(在 []
内)。
到目前为止一切顺利。
但要实际编译规则(从包含语义操作的模板表达式),您实际上还需要 Fusion 支持大序列:
#define BOOST_MAX_FUSION_VECTOR_SIZE 30
Note, besides that you're passing 3 arguments too many (_1 through _18 makes 18, but you already pass the hardcoded (ts, msgtype, seq_num)
so 15 would be enough).
但正如我之前的回答 (),我建议不要这样做。这只会使您的代码不可读,编译起来极其昂贵,而且通常不会带来有用的好处。
相反,请考虑使用 qi::_0
,它一次性传递整个合成属性序列。
或者根本不使用语义动作;
看妈,没有手!
我经常说我更愿意避免语义操作。原因:Boost Spirit: "Semantic actions are evil"?
在这种情况下,我建议进行简单的 Fusion 序列改编:
struct ImbalanceMsg {
timespec ts;
uint8_t msgtype;
uint64_t seq_num;
std::string symbol;
uint64_t symbol_seqnum;
uint64_t ref_price;
uint32_t paired_qty;
uint32_t total_imb_qty;
uint32_t mkt_imb_qty;
uint32_t auction_time;
char auction_type;
char imb_side;
uint64_t cont_clear_price;
uint64_t auction_int_clear_price;
uint64_t ssr_filling_price;
uint64_t ind_match_price;
uint64_t upper_collar;
uint64_t lower_collar;
uint32_t auction_status;
uint32_t freeze_status;
uint32_t num_ext;
};
BOOST_FUSION_ADAPT_STRUCT(ImbalanceMsg,
ts, msgtype, seq_num, symbol, symbol_seqnum, ref_price,
paired_qty, total_imb_qty, mkt_imb_qty, auction_time, auction_type, imb_side,
cont_clear_price, auction_int_clear_price, ssr_filling_price, ind_match_price, upper_collar,
lower_collar, auction_status, freeze_status, num_ext)
现在您可以简单地解析所有成员:
qi::rule<std::string::const_iterator, ImbalanceMsg()> m_wire_msg
= qi::attr(ts) >> qi::attr(msgtype) >> qi::attr(seq_num)
>> qi::as_string[*qi::alpha] >> "," // symbol
>> qi::ulong_ >> "," // symbol seq num
>> m_fixed_point >> "," // ref price
>> qi::uint_ >> "," // paired_qty
>> qi::uint_ >> "," // total_imb_qty
>> qi::uint_ >> "," // mkt_imb_qty
>> qi::uint_ >> "," // auction_time
>> qi::char_ >> "," // auction type
>> qi::char_ >> "," // imb side
>> m_fixed_point >> "," // cont_clear_price
>> m_fixed_point >> "," // auction_int_clear_price
>> m_fixed_point >> "," // ssr_filling_price
>> m_fixed_point >> "," // ind_match_price
>> m_fixed_point >> "," // upper_collar
>> m_fixed_point >> "," // lower_collar
>> qi::ushort_ >> "," // auction status
>> qi::ushort_ >> "," // freeze status
>> qi::ushort_;
并且属性传播是完全自动的:
#define BOOST_MAX_FUSION_VECTOR_SIZE 30
#define BOOST_PHOENIX_LIMIT 30
#define SPIRIT_ARGUMENTS_LIMIT 30
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/io.hpp>
#include <ctime>
namespace qi = boost::spirit::qi;
#define PRICE_MULT 10000
struct ImbalanceMsg {
timespec ts;
uint8_t msgtype;
uint64_t seq_num;
std::string symbol;
uint64_t symbol_seqnum;
uint64_t ref_price;
uint32_t paired_qty;
uint32_t total_imb_qty;
uint32_t mkt_imb_qty;
uint32_t auction_time;
char auction_type;
char imb_side;
uint64_t cont_clear_price;
uint64_t auction_int_clear_price;
uint64_t ssr_filling_price;
uint64_t ind_match_price;
uint64_t upper_collar;
uint64_t lower_collar;
uint32_t auction_status;
uint32_t freeze_status;
uint32_t num_ext;
};
BOOST_FUSION_ADAPT_STRUCT(ImbalanceMsg,
ts, msgtype, seq_num, symbol, symbol_seqnum, ref_price,
paired_qty, total_imb_qty, mkt_imb_qty, auction_time, auction_type, imb_side,
cont_clear_price, auction_int_clear_price, ssr_filling_price, ind_match_price, upper_collar,
lower_collar, auction_status, freeze_status, num_ext)
static inline std::ostream& operator<<(std::ostream& os, timespec) { return os << "(timespec:TODO)"; }
struct SimpleReal : qi::real_policies<double> {
template <typename It> static bool parse_exp(It, It) { return false; }
template <typename It> static bool parse_exp_n(It, It, int) { return false; }
template <typename It> static bool parse_nan(It, It, double) { return false; }
template <typename It> static bool parse_inf(It, It, double) { return false; }
};
int main() {
qi::rule<std::string::const_iterator, uint64_t()> m_fixed_point
= qi::real_parser<double, SimpleReal>{} [ qi::_val = PRICE_MULT*qi::_1 ];
timespec ts;
uint8_t msgtype = 105;
uint64_t seq_num = 42982201;
qi::rule<std::string::const_iterator, ImbalanceMsg()> m_wire_msg
= qi::attr(ts) >> qi::attr(msgtype) >> qi::attr(seq_num)
>> qi::as_string[*qi::alpha] >> "," // symbol
>> qi::ulong_ >> "," // symbol seq num
>> m_fixed_point >> "," // ref price
>> qi::uint_ >> "," // paired_qty
>> qi::uint_ >> "," // total_imb_qty
>> qi::uint_ >> "," // mkt_imb_qty
>> qi::uint_ >> "," // auction_time
>> qi::char_ >> "," // auction type
>> qi::char_ >> "," // imb side
>> m_fixed_point >> "," // cont_clear_price
>> m_fixed_point >> "," // auction_int_clear_price
>> m_fixed_point >> "," // ssr_filling_price
>> m_fixed_point >> "," // ind_match_price
>> m_fixed_point >> "," // upper_collar
>> m_fixed_point >> "," // lower_collar
>> qi::ushort_ >> "," // auction status
>> qi::ushort_ >> "," // freeze status
>> qi::ushort_;
ImbalanceMsg m;
std::string const s = "AAPL,1192101,157.56,0,200,0,1600,C,S,0,0,0,157.57,159140000,155980000,0,0,0";
bool ok = parse( s.begin(), s.end(), m_wire_msg, m );
std::cout << "ok=" << ok << "\n";
using boost::fusion::operator<<;
std::cout << m << "\n";
}
版画
ok=1
((timespec:TODO) i 42982201 AAPL 1192101 1575600 0 200 0 1600 C S 0 0 0 1575700 1591400000000 1559800000000 0 0 0)
使用qi::_0
您可以在此处阅读有关此方法的更多信息:
template <typename T> struct Factory {
template <typename Seq>
T operator()(Seq const& seq) const { return my_apply(Construct{}, seq); }
private:
struct Construct {
template <typename... I> T operator()(I... initializers) const
{ return T { initializers... }; }
};
};
Surprisingly boost::fusion::apply
still doesn't exist, so I'll add the my_apply
implementation from that answer (c++14).
现在您可以在语义操作中使用它了:
...
>> qi::ushort_) [ qi::_val = phi::bind(Factory<ImbalanceMsg>{}, qi::_0) ];
这样做的好处是不需要 Boost Fusion Adaptation,而且仍然不需要大量的占位符。
奖金
我也会做更简单的定点实解析:
qi::rule<std::string::const_iterator, uint64_t()> m_fixed_point
= qi::real_parser<double, SimpleReal>{} [ qi::_val = PRICE_MULT*qi::_1 ];
其中 SimpleReal
是不允许特殊表示(如科学记数法)的真实策略。
我一直在尝试各种方法,但仍然不太理解为什么以下操作失败并显示 'incomplete type' 错误
#define BOOST_PHOENIX_LIMIT 30
#define SPIRIT_ARGUMENTS_LIMIT 30
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <ctime>
#include <chrono>
#include <string>
#include <iomanip>
namespace qi = boost::spirit::qi;
namespace phi = boost::phoenix;
using namespace std::chrono_literals;
using namespace qi::labels;
using It = std::string::const_iterator;
#define PRICE_MULT 10000
class ImbalanceMsg
{
public:
ImbalanceMsg(){}
ImbalanceMsg(timespec ts,
uint8_t msgtype,
uint64_t seq_num,
std::string symbol,
uint64_t symbol_seqnum,
uint64_t ref_price,
uint32_t paired_qty,
uint32_t total_imb_qty,
uint32_t mkt_imb_qty,
uint32_t auction_time,
char auction_type,
char imb_side,
uint64_t cont_clear_price,
uint64_t auction_int_clear_price,
uint64_t ssr_filling_price,
uint64_t ind_match_price,
uint64_t upper_collar,
uint64_t lower_collar,
uint32_t auction_status,
uint32_t freeze_status,
uint32_t num_ext
) :
m_ref_price{ref_price},
m_paired_qty{paired_qty},
m_total_imb_qty{total_imb_qty},
m_mkt_imb_qty{mkt_imb_qty},
m_auction_time{auction_time},
m_auction_type{auction_type},
m_imb_side{imb_side},
m_cont_clear_price{cont_clear_price},
m_auction_int_clear_price{auction_int_clear_price},
m_ssr_filling_price{ssr_filling_price},
m_ind_match_price{ind_match_price},
m_upper_collar{upper_collar},
m_lower_collar{lower_collar},
m_auction_status{auction_status},
m_freeze_status{freeze_status},
m_num_ext{num_ext}
{}
// auto msg = parse( "105,42982201,15:00:05.553620224,AAPL,1192101,157.56,0,200,0,1600,C,S,0,0,0,157.57,159140000,155980000,0,0,0" );
std::string m_symbol;
uint64_t m_symbol_seqnum;
uint64_t m_ref_price;
uint32_t m_paired_qty;
uint32_t m_total_imb_qty;
uint32_t m_mkt_imb_qty;
uint32_t m_auction_time;
char m_auction_type;
char m_imb_side;
uint64_t m_cont_clear_price;
uint64_t m_auction_int_clear_price;
uint64_t m_ssr_filling_price;
uint64_t m_ind_match_price;
uint64_t m_upper_collar;
uint64_t m_lower_collar;
uint32_t m_auction_status;
uint32_t m_freeze_status;
uint32_t m_num_ext;
};
int main() {
std::string s = "AAPL,1192101,157.56,0,200,0,1600,C,S,0,0,0,157.57,159140000,155980000,0,0,0";
timespec ts;
uint8_t msgtype = 105;
uint64_t seq_num = 42982201;
qi::uint_parser<uint32_t, 10, 1, 6> int_part;
qi::uint_parser<uint8_t , 10, 1, 1> m_digit;
qi::rule<std::string::iterator, uint64_t()>
m_fixed_point = int_part[qi::_val = qi::_1 * PRICE_MULT] >>
-("." >> -(m_digit[qi::_val += qi::_1 * 1000])
>> -(m_digit[qi::_val += qi::_1 * 100])
>> -(m_digit[qi::_val += qi::_1 * 10])
>> -(m_digit[qi::_val += qi::_1 ])
);
qi::rule<std::string::iterator, ImbalanceMsg()>
m_wire_msg = ( qi::as_string[*qi::alpha] >> "," // symbol
>> qi::ulong_ >> "," // symbol seq num
>> m_fixed_point >> "," // ref price
>> qi::uint_ >> "," // paired_qty
>> qi::uint_ >> "," // total_imb_qty
>> qi::uint_ >> "," // mkt_imb_qty
>> qi::uint_ >> "," // auction_time
>> qi::char_ >> "," // auction type
>> qi::char_ >> "," // imb side
>> m_fixed_point >> "," // cont_clear_price
>> m_fixed_point >> "," // auction_int_clear_price
>> m_fixed_point >> "," // ssr_filling_price
>> m_fixed_point >> "," // ind_match_price
>> m_fixed_point >> "," // upper_collar
>> m_fixed_point >> "," // lower_collar
>> qi::ushort_ >> "," // auction status
>> qi::ushort_ >> "," // freeze status
>> qi::ushort_
)[qi::_val = phi::construct<ImbalanceMsg>(ts, msgtype, seq_num,
qi::_1, //symbol
qi::_2, //market_id
qi::_3, //system_id
qi::_4, //exchange_code
qi::_5, //security_type
qi::_6, //lot_size
qi::_7, // prev_close_price
qi::_8, // prev_close_volume
qi::_9, // price_resolution
qi::_10, // round_lot
qi::_11, // mpv
qi::_12,
qi::_13,
qi::_14,
qi::_15,
qi::_16,
qi::_17,
qi::_18
)];
ImbalanceMsg m;
bool ok = parse( s.begin(), s.end(), m_wire_msg, m );
std::cout << "ok=" << ok << std::endl;
}
与 ImbalanceMsg 相比,我没有遇到属性较少的较小 类 的相同问题。
我还有其他几种类型的消息 类,它们的代码相似,但都可以正常编译。
有人可以指点一下吗?
只要有一个占位符就可以编译语义动作表达式(在 []
内)。
到目前为止一切顺利。
但要实际编译规则(从包含语义操作的模板表达式),您实际上还需要 Fusion 支持大序列:
#define BOOST_MAX_FUSION_VECTOR_SIZE 30
Note, besides that you're passing 3 arguments too many (_1 through _18 makes 18, but you already pass the hardcoded
(ts, msgtype, seq_num)
so 15 would be enough).
但正如我之前的回答 (
相反,请考虑使用 qi::_0
,它一次性传递整个合成属性序列。
或者根本不使用语义动作;
看妈,没有手!
我经常说我更愿意避免语义操作。原因:Boost Spirit: "Semantic actions are evil"?
在这种情况下,我建议进行简单的 Fusion 序列改编:
struct ImbalanceMsg {
timespec ts;
uint8_t msgtype;
uint64_t seq_num;
std::string symbol;
uint64_t symbol_seqnum;
uint64_t ref_price;
uint32_t paired_qty;
uint32_t total_imb_qty;
uint32_t mkt_imb_qty;
uint32_t auction_time;
char auction_type;
char imb_side;
uint64_t cont_clear_price;
uint64_t auction_int_clear_price;
uint64_t ssr_filling_price;
uint64_t ind_match_price;
uint64_t upper_collar;
uint64_t lower_collar;
uint32_t auction_status;
uint32_t freeze_status;
uint32_t num_ext;
};
BOOST_FUSION_ADAPT_STRUCT(ImbalanceMsg,
ts, msgtype, seq_num, symbol, symbol_seqnum, ref_price,
paired_qty, total_imb_qty, mkt_imb_qty, auction_time, auction_type, imb_side,
cont_clear_price, auction_int_clear_price, ssr_filling_price, ind_match_price, upper_collar,
lower_collar, auction_status, freeze_status, num_ext)
现在您可以简单地解析所有成员:
qi::rule<std::string::const_iterator, ImbalanceMsg()> m_wire_msg
= qi::attr(ts) >> qi::attr(msgtype) >> qi::attr(seq_num)
>> qi::as_string[*qi::alpha] >> "," // symbol
>> qi::ulong_ >> "," // symbol seq num
>> m_fixed_point >> "," // ref price
>> qi::uint_ >> "," // paired_qty
>> qi::uint_ >> "," // total_imb_qty
>> qi::uint_ >> "," // mkt_imb_qty
>> qi::uint_ >> "," // auction_time
>> qi::char_ >> "," // auction type
>> qi::char_ >> "," // imb side
>> m_fixed_point >> "," // cont_clear_price
>> m_fixed_point >> "," // auction_int_clear_price
>> m_fixed_point >> "," // ssr_filling_price
>> m_fixed_point >> "," // ind_match_price
>> m_fixed_point >> "," // upper_collar
>> m_fixed_point >> "," // lower_collar
>> qi::ushort_ >> "," // auction status
>> qi::ushort_ >> "," // freeze status
>> qi::ushort_;
并且属性传播是完全自动的:
#define BOOST_MAX_FUSION_VECTOR_SIZE 30
#define BOOST_PHOENIX_LIMIT 30
#define SPIRIT_ARGUMENTS_LIMIT 30
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/io.hpp>
#include <ctime>
namespace qi = boost::spirit::qi;
#define PRICE_MULT 10000
struct ImbalanceMsg {
timespec ts;
uint8_t msgtype;
uint64_t seq_num;
std::string symbol;
uint64_t symbol_seqnum;
uint64_t ref_price;
uint32_t paired_qty;
uint32_t total_imb_qty;
uint32_t mkt_imb_qty;
uint32_t auction_time;
char auction_type;
char imb_side;
uint64_t cont_clear_price;
uint64_t auction_int_clear_price;
uint64_t ssr_filling_price;
uint64_t ind_match_price;
uint64_t upper_collar;
uint64_t lower_collar;
uint32_t auction_status;
uint32_t freeze_status;
uint32_t num_ext;
};
BOOST_FUSION_ADAPT_STRUCT(ImbalanceMsg,
ts, msgtype, seq_num, symbol, symbol_seqnum, ref_price,
paired_qty, total_imb_qty, mkt_imb_qty, auction_time, auction_type, imb_side,
cont_clear_price, auction_int_clear_price, ssr_filling_price, ind_match_price, upper_collar,
lower_collar, auction_status, freeze_status, num_ext)
static inline std::ostream& operator<<(std::ostream& os, timespec) { return os << "(timespec:TODO)"; }
struct SimpleReal : qi::real_policies<double> {
template <typename It> static bool parse_exp(It, It) { return false; }
template <typename It> static bool parse_exp_n(It, It, int) { return false; }
template <typename It> static bool parse_nan(It, It, double) { return false; }
template <typename It> static bool parse_inf(It, It, double) { return false; }
};
int main() {
qi::rule<std::string::const_iterator, uint64_t()> m_fixed_point
= qi::real_parser<double, SimpleReal>{} [ qi::_val = PRICE_MULT*qi::_1 ];
timespec ts;
uint8_t msgtype = 105;
uint64_t seq_num = 42982201;
qi::rule<std::string::const_iterator, ImbalanceMsg()> m_wire_msg
= qi::attr(ts) >> qi::attr(msgtype) >> qi::attr(seq_num)
>> qi::as_string[*qi::alpha] >> "," // symbol
>> qi::ulong_ >> "," // symbol seq num
>> m_fixed_point >> "," // ref price
>> qi::uint_ >> "," // paired_qty
>> qi::uint_ >> "," // total_imb_qty
>> qi::uint_ >> "," // mkt_imb_qty
>> qi::uint_ >> "," // auction_time
>> qi::char_ >> "," // auction type
>> qi::char_ >> "," // imb side
>> m_fixed_point >> "," // cont_clear_price
>> m_fixed_point >> "," // auction_int_clear_price
>> m_fixed_point >> "," // ssr_filling_price
>> m_fixed_point >> "," // ind_match_price
>> m_fixed_point >> "," // upper_collar
>> m_fixed_point >> "," // lower_collar
>> qi::ushort_ >> "," // auction status
>> qi::ushort_ >> "," // freeze status
>> qi::ushort_;
ImbalanceMsg m;
std::string const s = "AAPL,1192101,157.56,0,200,0,1600,C,S,0,0,0,157.57,159140000,155980000,0,0,0";
bool ok = parse( s.begin(), s.end(), m_wire_msg, m );
std::cout << "ok=" << ok << "\n";
using boost::fusion::operator<<;
std::cout << m << "\n";
}
版画
ok=1
((timespec:TODO) i 42982201 AAPL 1192101 1575600 0 200 0 1600 C S 0 0 0 1575700 1591400000000 1559800000000 0 0 0)
使用qi::_0
您可以在此处阅读有关此方法的更多信息:
template <typename T> struct Factory {
template <typename Seq>
T operator()(Seq const& seq) const { return my_apply(Construct{}, seq); }
private:
struct Construct {
template <typename... I> T operator()(I... initializers) const
{ return T { initializers... }; }
};
};
Surprisingly
boost::fusion::apply
still doesn't exist, so I'll add themy_apply
implementation from that answer (c++14).
现在您可以在语义操作中使用它了:
...
>> qi::ushort_) [ qi::_val = phi::bind(Factory<ImbalanceMsg>{}, qi::_0) ];
这样做的好处是不需要 Boost Fusion Adaptation,而且仍然不需要大量的占位符。
奖金
我也会做更简单的定点实解析:
qi::rule<std::string::const_iterator, uint64_t()> m_fixed_point
= qi::real_parser<double, SimpleReal>{} [ qi::_val = PRICE_MULT*qi::_1 ];
其中 SimpleReal
是不允许特殊表示(如科学记数法)的真实策略。