Boost :: Spirit和Intel编译器编译错误

时间:2016-04-07 12:57:03

标签: boost-spirit icc

我使用Boost Spirit编写了一个数学表达式解析器,它解析了一个简单的幂表达式(一个更大的解析器的最小例子):

#include <iostream>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/qi.hpp>
#include <cmath>
#include <string>
using namespace std;

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

struct power_ {
    template <typename X, typename Y> struct result {
        typedef X type;
    };

    template <typename X, typename Y> X operator()(X x, Y y) const {
        return std::pow(x, y);
    }
};

struct math : qi::grammar<std::string::const_iterator, double(),
                          ascii::space_type> {
    math() : math::base_type(expr) {
        boost::phoenix::function<power_> power;

        expr = factor[qi::_val = qi::_1];

        factor = arg[qi::_val = qi::_1] >>
                 *("**" >> arg [qi::_val = power(qi::_val, qi::_1)]);

        arg = qi::double_[qi::_val = qi::_1];
    }

    qi::rule<std::string::const_iterator, double(), ascii::space_type> expr, arg, factor;
};

int main(int argc, char **argv){
    math math;

    string expr = "2**3";
    double result;

    string::const_iterator iter = expr.begin();
    string::const_iterator end = expr.end();
    phrase_parse(iter, end, math, ascii::space, result);

    cout << "Expression: " << expr << endl;
    cout << "Result: " << result << endl;

    return 0;
}

使用GCC 4.8.4和Clang 3.9编译此代码很好,但在使用英特尔编译器(版本12.1.6)进行编译时会产生巨大的编译错误。编译器输出的相关部分是

/user/home/gent/vsc408/vsc40826/boost_1_60_0/build/include/boost/utility/result_of.hpp(189): error: too few arguments for class template "power_::result"
  struct result_of_nested_result : F::template result<FArgs>

这似乎指出了{:: 3}}提到的boost :: result_of和C ++ 11的问题。但是,当我更改struct power_

的定义时
struct power_ {
    template <class> struct result;

    template <class F, typename X, typename Y>
    struct result < F(X, Y) > {
        typedef X type;
    };

    template <typename X, typename Y> X operator()(X x, Y y) const {
        return std::pow(x, y);
    }
};

我仍然收到错误:

/user/home/gent/vsc408/vsc40826/boost_1_60_0/build/include/boost/phoenix/core/detail/preprocessed/function_eval_10.hpp(135): error: initial value of reference to non-const must be an lvalue
                  return boost::phoenix::eval(f, ctx)(help_rvalue_deduction(boost::phoenix::eval(a0, ctx)) , help_rvalue_deduction(boost::phoenix::eval(a1, ctx)));

在任何精神包含之前添加#define BOOST_RESULT_OF_USE_DECLTYPE也没有帮助,因为编译然后在第一个精神包括失败。

有人知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

好的,只想出这个。 Boost :: Phoenix显然已经转而通过引用返回。以下版本的struct power_有效:

struct power_ {
    template <class> struct result;

    template <class F, typename X, typename Y>
    struct result < F(X, Y) > {
        typedef X& type;
    };

    template <typename X, typename Y> X& operator()(X &x, Y y) const {
        x = std::pow(x, y);
        return x;
    }
};