#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/phoenix/function/adapt_function.hpp>

struct add_operand { 
    template<typename...> struct result { typedef void type; };
    template<typename L, typename R>
    void operator()(L& lhs, R rhs) const { lhs += rhs; } 
};

struct sub_operand { 
    template<typename...> struct result { typedef void type; };
    template<typename L, typename R>
    void operator()(L& lhs, R rhs) const { lhs -= rhs; } 
};

int main()
{
    const std::string INPUT_DATA = "12e-1 + 3.4 - .67";
    typedef std::string::const_iterator iterator_type;
    iterator_type begin = std::begin(INPUT_DATA);
    iterator_type end   = std::end(INPUT_DATA);

    namespace qi    = boost::spirit::qi;
    namespace ascii = boost::spirit::qi::ascii;
    namespace phx   = boost::phoenix;

    bool ok;
    double result;
    {
        using namespace qi;
        using phx::bind;

        auto parser = 
               double_                  [_val  = _1]
            >> *(   (lit('+') >> double_[bind(add_operand(), _val, _1)])
                  | (lit('-') >> double_[bind(sub_operand(), _val, _1)])
                );

        ok = phrase_parse(begin, end, parser, ascii::space, result);
    }

    if (ok  && begin == end)
        std::cout << "parsed, result = " << result << std::endl;
    else
        std::cout << "not parsed" << std::endl;
}
