I have a case where I\'d like to filter the value that comes up as a synthesized attribute inside of a rule through a std::map.
Reposting from comment
Try qi::_val = phx::ref(myMap)[qi::_1]
rather than qi::_val = phx::at(myMap, qi::_1)
.
The problem is that the return type of phoenix::at is defined in this header as container::value_type
. This is a pair in the case of a map. Simply specializing the result for map makes it work (using ref as noted by 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";
}
}