( qi::_bool >> qi::_bool >> qi::_bool >> qi::_bool)
[px::bind(&Bool4Function, spirit::_val, spirit::_1, spirit::_2, spirit::_3, spirit::_4)]
虽然它本身没问题,但是到处都使用它只会让代码显得丑陋和混乱,即使使用命名空间部分也无济于事。
这就是为什么我想将这个表达式提取成一个独立的语法。
因此,我尝试了这个方法(感谢ildjarn提供测试平台):
///// grammar implementation /////
#include <boost/fusion/include/vector10.hpp>
#include <boost/spirit/include/qi_bool.hpp>
#include <boost/spirit/include/qi_char_.hpp>
#include <boost/spirit/include/qi_grammar.hpp>
#include <boost/spirit/include/qi_operator.hpp>
#include <boost/spirit/include/qi_rule.hpp>
#include <boost/spirit/include/qi_string.hpp>
struct FourBools : boost::spirit::qi::grammar<
char const*,
boost::fusion::vector4<bool, bool, bool, bool>()
>
{
typedef boost::fusion::vector4<bool, bool, bool, bool> attribute_type;
FourBools() : base_type(start_)
{
using boost::spirit::bool_;
start_
= "4bools:"
>> bool_ >> ','
>> bool_ >> ','
>> bool_ >> ','
>> bool_ >> ';'
;
}
private:
boost::spirit::qi::rule<
base_type::iterator_type,
base_type::sig_type
> start_;
};
FourBools const fourBools;
///// demonstration of use /////
#include <string>
#include <ios>
#include <iostream>
#include <boost/fusion/include/at_c.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/qi_action.hpp>
#include <boost/spirit/include/qi_parse.hpp>
void noDice(bool a, bool b, bool c, bool d)
{
}
void worksFine(boost::fusion::vector4<bool, bool, bool, bool> a)
{
}
int main()
{
namespace phx = boost::phoenix;
namespace spirit = boost::spirit;
std::string const input("4bools:true,true,true,false;");
char const* first = input.c_str();
char const* const last = first + input.size();
bool const success = spirit::qi::parse(
first, last,
fourBools[phx::bind(&noDice, spirit::_1)]
);
if (!success)
std::cout << "parse() failed\n";
else if (first != last)
std::cout << "didn't consume all input\n";
std::cout.flush();
}
如果不将 fourBools[phx::bind(&noDice, spirit::_1)]
替换为 fourBools[phx::bind(&worksFine, spirit::_1)]
,则代码无法编译通过。
这意味着,我的问题在于参数的拆分,以匹配要调用的函数的签名,因为参数数量在签名级别上有所不同(一个由四个布尔值组成的元组,与四个独立的布尔值)。
是否可以直接使用 phoenix 占位符进行拆分,而不是编写包装器将元组转换为现有需要单独使用它们的函数的单独参数? 如果可以,那么语法应该是什么?
毕竟,像 ( qi::_bool >> qi::_bool >> qi::_bool >> qi::_bool)
这样的内联版本,在通过 spirit::_1 - spirit::_4
占位符“解包”后,可以正常工作。
这使我觉得这个版本也返回了一个元组,并且可以通过上述方法进行拆分,而不像返回一个元组的语法。
我该如何处理这个问题?