我有一个案例,我希望通过std :: map过滤作为规则内部的合成属性的值。
我的尝试:
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <iostream>
#include <vector>
#include <map>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
int main() {
std::map<unsigned int, unsigned int> myMap;
myMap[1] = 100; myMap[2] = 200; myMap[3] = 300;
std::string test = "1 2 3";
std::vector<unsigned int> results;
qi::rule<std::string::iterator, unsigned int()> r
= qi::uint_ [qi::_val = phx::at(myMap, qi::_1)];
qi::parse(test.begin(), test.end(), ( r % " " ), results);
BOOST_FOREACH(unsigned int &x, results) {
std::cout << x << "\n";
}
}
由于凤凰对stl containers的支持,我想我的印象是,这应该有效。但是我在规则行上遇到编译错误。如果我用经典的无意义[qi::_val = qi::_1]
替换语义动作(毫不奇怪),这个错误就消失了。
像往常一样,MSVS10下的编译器错误令人震惊,但这是第一次提到我的代码文件:(在C:\ code \ Compiler2 \ spirit_test.cpp(25)...第25行是规则{{ 1}})
r
答案 0 :(得分:3)
重新发布评论
尝试qi::_val = phx::ref(myMap)[qi::_1]
而不是qi::_val = phx::at(myMap, qi::_1)
。
答案 1 :(得分:2)
问题是phoenix :: at的返回类型在this header中被定义为container::value_type
。在地图的情况下,这是一对。只需专门化地图的结果就可以了(使用参考ildjarn所说的参考)。
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <iostream>
#include <vector>
#include <map>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace boost { namespace phoenix { namespace stl {
template <typename This, typename Key, typename Value, typename Compare, typename Allocator, typename Index>
struct at_impl::result<This(std::map<Key,Value,Compare,Allocator>&, Index)>
{
typedef Value & type;
};
template <typename This, typename Key, typename Value, typename Compare, typename Allocator, typename Index>
struct at_impl::result<This(std::map<Key,Value,Compare,Allocator> const&, Index)>
{
typedef Value const& type;
};
}}}
int main() {
std::map<unsigned int, unsigned int> myMap;
myMap[1] = 100; myMap[2] = 200; myMap[3] = 300;
std::string test = "1 2 3";
std::vector<unsigned int> results;
qi::rule<std::string::iterator, unsigned int()> r
= qi::uint_ [qi::_val = phx::at(phx::cref(myMap), qi::_1)];
qi::parse(test.begin(), test.end(), ( r % " " ), results);
BOOST_FOREACH(unsigned int &x, results) {
std::cout << x << "\n";
}
}