2017-07-06 66 views
3

我嘗試將float或int的簡單列表解析爲變體的向量。我在Windows上使用boost 1.64(mingw 64bit)。用助推精神解析變體列表X3

下面是一個小例子:

#include <boost/spirit/home/x3/support/ast/variant.hpp> 
#include <boost/fusion/adapted/struct.hpp> 
#include <boost/spirit/home/x3.hpp> 

#include <iostream> 
#include <vector> 

namespace x3 = boost::spirit::x3; 

struct var : x3::variant<int, float> { 
    using base_type::base_type; 
    using base_type::operator=; 
}; 

struct block { 
    bool dummy; // needed to make newer boost version compile 
    std::vector<var> vars; 
}; 

BOOST_FUSION_ADAPT_STRUCT(block, 
    (bool, dummy), 
    (std::vector<var>, vars) 
); 

x3::rule<class var, var>  const r_var = "var"; 
x3::rule<class block, block> const r_block = "block"; 

auto const r_var_def = x3::float_ | x3::int_; 
auto const r_block_def = x3::attr(true) >> *x3::lit(";") >> *(r_var >> -x3::lit(",")); 

BOOST_SPIRIT_DEFINE(r_var, r_block); 

bool parse(std::string const &txt, block &ast) 
{ 
    using boost::spirit::x3::phrase_parse; 
    using boost::spirit::x3::space; 

    auto iter = txt.begin(); 
    auto end = txt.end(); 

    const bool parsed = phrase_parse(iter, end, r_block, space, ast); 
    return parsed && iter == end; 
} 

int main() { 
    std::vector<std::string> list = { 
     "1, 3, 5.5", 
     ";1.0, 2.0, 3.0, 4.0" 
    }; 

    for (const auto&i : list) { 
     block ast; 
     if (parse(i, ast)) { 
      std::cout << "OK: " << i << std::endl; 
     } else { 
      std::cout << "FAIL: " << i << std::endl; 
     } 
    } 
} 

GCC 7.1提供了以下錯誤:

..\parser\parser.cpp:41:68: required from here 
..\..\win64\include/boost/spirit/home/x3/nonterminal/detai/rule.hpp:313:24: error: use of deleted function 'var::var(const var&)' 
      value_type made_attr = make_attribute::call(attr); 
         ^~~~~~~~~ 

任何想法,爲什麼GCC不編譯它?它雖然與Clang一起工作。

住在Coliru(切換到鐺++看到它的工作)。

回答

4

看來使用繼承的特殊成員有問題。兩種解決方法:

using var = x3::variant<int, float>; 

或者:

struct var : x3::variant<int, float> { 
    var   (  ) = default; 
    var   (var const&) = default; 
    var& operator= (var const&) = default; 
    using base_type::base_type; 
    using base_type::operator=; 
}; 
+0

非常感謝你。 –