2017-07-06 5 views
3

J'essaye d'analyser une simple liste de float ou int dans un vecteur de variante. J'utilise boost 1.64 sur Windows (mingw 64bit).Analyse de la liste des variantes avec boost spirit X3

Voici un exemple minimal:

#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 donne l'erreur suivante:

..\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); 
         ^~~~~~~~~ 

Toutes les idées, pourquoi GCC ne compile pas? Cela fonctionne avec Clang cependant.

En direct sur Coliru (passez à clang ++ pour le voir fonctionner).

Répondre

4

Il semble qu'il y ait un problème lors de l'utilisation des membres spéciaux hérités. Deux solutions de contournement:

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

Autre possibilité:

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

Merci beaucoup. –