Domanda

Sto scrivendo una grammatica Boost Spirito in testo parse in un vettore di questi le strutture:

struct Pair
{
    double a;
    double b;
};

BOOST_FUSION_ADAPT_STRUCT(
    Pair,
    (double, a)
    (double, a)
)

Questa grammatica è una regola come questa:

qi::rule<Iterator, Pair()> pairSequence;

Tuttavia, la grammatica effettiva di pairSequence è questo:

double_ % separator

Voglio questa grammatica per produrre un Pair con a pari al doppio e b uguale ad una costante. Voglio fare qualcosa di simile:

pairSequence = double_[_val = Pair(_1, DEFAULT_B)] % separator;

È possibile che questo non compila, ovviamente. Ho provato ad aggiungere un costruttore per Pair, ma ho ancora errori di compilazione ( nessuna funzione di corrispondenza per la chiamata a 'Coppia :: Coppia (spinta const :: :: Phoenix attore> &, doppio)' ).

È stato utile?

Soluzione

Prima di tutto, la firma di pairSequence deve essere:

qi::rule<Iterator, std::vector<Pair>()> pairSequence; 

come l'operatore lista espone una std::vector<Pair> come suo attributo.

Tutte le funzioni chiamate dall'interno di un'azione semantica devono essere 'pigro', quindi è necessario utilizzare phoenix:

namespace phx = boost::phoenix;

pairSequence = 
    double_[
        phx::push_back(_val, 
            phx::construct<Pair>(_1, phx::val(DEFAULT_B))
        )
    ] % separator
; 

Un'altra possibilità sarebbe quella di aggiungere un costruttore (non esplicito) a Pair:

struct Pair         
{         
    Pair(double a) : a(a), b(DEFAULT_B) {}

    double a;         
    double b;         
};         

che consente di semplificare la grammatica:

pairSequence = double_ % separator; 

e si basa completamente sul Spirito built-in regole di attributo di propagazione.

A proposito, per tutto questo al lavoro, non c'è bisogno di adattarsi Pair come una sequenza di fusione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top