3

テキストをこれらの構造体のベクトルに解析する Boost Spirit 文法を書いています。

struct Pair
{
    double a;
    double b;
};

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

この文法には次のような規則があります。

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

ただし、 の実際の文法pairSequenceは次のとおりです。

double_ % separator

Pairこの文法でwithaを double にb等しく、なんらかの定数に等しくするようにしたいと考えています。私はこのようなことをしたい:

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

もちろん、上記はコンパイルされません。にコンストラクターを追加しようとしましたPairが、まだコンパイル エラーが発生します ( 'Pair::Pair(const boost::phoenix::actor >&, double)' の呼び出しに一致する関数がありません)。

4

1 に答える 1

6

まず、署名は次のようにpairSequenceする必要があります。

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

リスト演算子が astd::vector<Pair>をその属性として公開するためです。

セマンティック アクション内から呼び出されるすべての関数は「遅延」でなければならないため、phoenix を利用する必要があります。

namespace phx = boost::phoenix;

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

別の可能性は、(非明示的な) コンストラクターを に追加することPairです。

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

    double a;         
    double b;         
};         

これにより、文法を簡素化できます。

pairSequence = double_ % separator; 

また、Spirit の組み込みの属性伝播規則に完全に依存しています。

ところで、これが機能するためPairに、Fusion シーケンスとして適応する必要はありません。

于 2010-06-27T17:37:11.450 に答える