2016-04-07 7 views
1

私は、単純なパワー式(はるかに大きいパーサの最小限の一例)を解析し、ブーストスピリットを使って数式パーサを書いた:ブースト::精神とIntelコンパイラのコンパイル・エラー

#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> 

ですこれはhttp://www.boost.org/doc/libs/1_56_0/libs/utility/utility.htm#result_ofで述べたように、ブースト:: 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); 
    } 
}; 

を私はまだエラーを取得:

含めるコンパイルは、最初の精神に障害が発生したとして任意の精神は、いずれか助けていませんが含ま前 #define BOOST_RESULT_OF_USE_DECLTYPEを追加
/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))); 

誰もこの問題を解決する方法を知っていますか?

+0

問題は1.56以上のBoostバージョンでのみ発生します。 –

答えて

1

これはわかりました。ブースト::フェニックスは明らかに参照によって戻ってきました。 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; 
    } 
}; 
関連する問題