我正在使用 QI 和 Phoenix,我想编写一个返回 4 个布尔值的小语法,这些布尔值将用作语义操作中函数调用的参数。
我有几个需要这些东西的功能,到目前为止我已经使用了这种方法:
( 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,
这让我觉得这个版本好像也返回一个元组,并且在某种程度上无法使用上述方法解包,这与返回一个的语法不同。
我该如何处理?