問題タブ [boost-proto]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - boost.proto + 式ツリーを適切に変更する
背景の質問: boost.proto + 式ツリーを構築する前に無効な端末を検出します。
こんにちは、私が達成しようとしているのは
- 式ツリーのコピーを作成します。ここで、すべてのベクトルが開始反復子に置き換えられます (私の場合は生のポインターです)。
- イテレータをその場でインクリメントする
- ツリーのイテレータを逆参照しますが、その部分は比較的簡単なはずです。
だから、1.私はこのコードで終わった
上記は、すべてのベクトルがポインターに置き換えられたツリーの作成に成功しました。ここまでは順調ですね。ここで、反復子をインクリメントしてみます。イテレータを進めるほうがよいことに気付いたので、1 つの変換だけで、ランダム アクセス イテレータのほとんどの動作を得ることができました (逆参照は、もう 1 つの欠落している部分です)。2. の場合、必要な変換は
さて、メイン関数で
次のエラー メッセージが表示されます (ジャンクは除外されます)。
array.cpp:361:13: エラー: 読み取り専用の場所の割り当て
気になるのは '((* & var))' の部分です...これを修正するために何をすべきか理解できません。よろしくお願いします。
PS 無関係なこと:変換で少し遊んだ後、私が使用している一般的なパターンは次のとおりです。
- 木をどうするか決める
- 操作を実行するプリミティブ変換を作成する
- 変換が適用されるべき場所を認識する文法を書き、以前に定義された変換を使用します
これは合理的だと思いますか?つまり、単一の種類のノードに対して基本的な操作を実行するだけでも、大量のコードになります。コンテキストを使用すると、ノード タイプを区別して、一度に複数の op を定義できます。変換でもこれを行うことは可能ですか? 使用される一般的なパターンは何ですか?
c++ - boost.proto + ドメイン固有の式ラッパーから式をアンラップ
背景の質問: boost.proto + 式ツリーを適切に変更する
value_type
こんにちは、 a からを抽出する次の変換を検討してvector_expr
ください (前の質問を参照)
上記のコードを使用して、通常の C++ プロモーション ルールと Boost.TypeOf マジックを適用して取得される式ツリーに「最大」value_type を提供できます。上記は次のように使用されます
しかし今、次のコード (前の質問を確認してください: boost.proto + 適切な式ツリーを変更し、受け入れられた回答のコード) が壊れています (私の喜びのために、通常の巨大なテンプレートのインスタンス化エラーのバックトレースで)
理由は簡単です。のタイプtypename boost::result_of<vector_begin_algo(a+b)>::type
は次のとおりです。
したがって、外部vector_expr<...>
はネストされた の評価をトリガーしますvalue_type
が、アルゴリズムはネストされたfromdeduce_value_type
を抽出する方法を知りません。1 つの解決策は、新しい特性を定義し、次のように変更することです。value_type
vector_iterator<double*>
deduce_value_type
このアプローチにはいくつかの問題がありますが、最も重要なのは、構造体で定義するのに便利な typedef または static 定数ごとにvector_expr
、式をコンパイルするためだけに上記のすべてを実行する必要があることです。 IS-NOT vector-expression であり、変換されたツリーに対応するために vector_expr のインターフェイスを拡大しても意味がありません。
問題は、vector_expr
ツリーを変換し、ベクトル ノードをイテレータ ノードに変換すると同時に、ツリー自体からベクトル性を削除して、上記の問題が発生しないようにする方法があるということです。よろしくお願いします。
更新 申し訳ありませんが、何を達成すべきか(私が思うに)がより明確になったので、質問の最後の部分を変更しました。とりあえず自力で解決しようとして部分的に成功(?)したのですが、もっといい方法があるはず(だからまだ助けが必要です!)。
問題は、すべてのツリーノードがラップされているvector_expr
ことに起因しているように思えます。これには、端末に要件を課すという副作用があります(主に、正常にコンパイルするための静的なもの)。OTOH、有効なものvector_exp
が構築されると(つまり、 に従うvector_grammar
)、それ以上のチェックなしで有効な iterator_tree に変換できます。
vector_expr
ツリー内のすべてのノードを「proto::expr」に戻す変換を作成しようとしました。コードは次のとおりです。
c++ - Boost.Protoおよび複雑な変換
私はProtoを使って、幾何学的ベクトルを操作するDSELを構築しようとしています。割り当て式を受け取り、コンポーネントごとに展開する変換を作成しようとしています。たとえば、私は置き換えたい
に
これまでのところ、変換と組み合わせて、各ベクトルコンポーネントの式を再帰的に展開する変換テンプレートを作成することで、ほとんどの場合それを機能させることができました。unroll_vector_expr
distribute_subscript
boost::result_of
とで使用される「パラメータ」の論理的根拠が何であるか理解していないようですresult_of::make_expr
。ドキュメント、例、内部コードが混在しているようですExpr
、、。何をいつ使用すれば、実際の結果タイプと一致するのかわかりません。現在、エラーメッセージを調べ、との不一致を修正することで、エラーを試行して機能させました。ただし、式をディープコピーするとすぐに、ターミナルは参照によって保持されなくなり、コードが失敗します。impl::expr
impl::expr_param
result_type
const
&
からの結果とresult_type
一致し、値と参照の両方で保持されるように変換を作成するにはどうすればよいですか?operator ()
terminal
更新: Ericの回答後にコードが更新されました。result_type
との間で残っている唯一の不一致make_expr
は、の最初のインスタンス化に対するものですunroll_vector_expr_c
。ここで、は値ではなくconst参照terminal< mpl::size_t< 0 > >::type
によって保持されます。不思議なことに、同じテンプレートをより高いインデックスでインスタンス化しても、この問題は発生しません。
更新distribue_subscript
:変換を変更して添え字インデックスを値で強制的に取得した後、コードを完全に機能させることができました:
c++ - このプロト/フェニックスのおもちゃの例がクラッシュするのはなぜですか?
私はプロトとフェニックスを実験していますが、最初のおもちゃの例の1つがクラッシュし、どこを見ればよいのかわかりません。#boost IRCチャネルの誰かが、フェニックス式ツリーが最初にディープコピーされるように(x
構築時にぶら下がっている参照が残らないように)指示されたので、式をでラップしましたboost::proto::deep_copy
。しかし、それはうまくいきませんでした。-O2
フラグを付けてコンパイルするとクラッシュし、省略しても正常に動作します。
これが出力されることを期待していますhellobye
。
c++ - BoostC++フェニックス式ツリーの変換
Boost Phoenixの記事「式ツリーの変換」では、カスタムクラスの特殊化のセットを使用して、バイナリ算術式を反転しています。invert_actions
たとえば、;a+b
になります。になります; 両方ともその逆です。a-b
a*b
a/b
これには、式ツリーの再帰的なトラバーサルが含まれますが、明示的に処理されていない演算子を含む式が検出されると、このトラバーサルは停止します。たとえば、_1+_2-_3
はになりますが_1-_2+_3
、その_1+_1&_2
ままになります(のハンドラーはありません&
)。let(_a = 1, _b = 2) [ _a+_b ]
また、変更されません。
これは記事の意図どおりだと思っていましたが、最後にリストされているテストを見ると、変更されることif_(_1 * _4)[_2 - _3]
が予想されます。提供されたコード(ここ)では、そうではないことがわかりました。
次に、明示的にリストされた(n-ary)演算子のセットすべてに適用される一般的なBoostPhoenix式ツリー変換を定義するにはどうすればよいですか。他を変更せずに残しますか?
いくつかのコードが役立つ場合があります。次のC++11コード(自動)を出力したいのですが、;0
ではありません。、またはその他の演算子/ステートメントを明示的に処理することなく。2
&
c++ - BoostPhoenix式内の関数本体の変換
Boost Phoenix式の変換に関数本体を含めるにはどうすればよいですか?
たとえば、Boost Phoenix Starter Kitのレイジー関数セクションに基づいて構築し、レイジー加算関数を作成しました。
次に、前の質問からの単純なプラスからマイナスへの変換を準備します。これを次に示します。
ただし、以下に示すようにlambda
、を使用して逆フェニックス式をmy_add
引数に適用すると、意図した逆変換が達成されていないようです。フェニックス内で関数呼び出しを実装するための推奨される方法はありますか?それはそのような変換を容易にすることができますか?
c++ - Boost C++ Phoenix ユーザー定義引数での添字 operator[] エラー
などの既存の Boost Phoenix (プレースホルダー) 引数_1
を使用して、配列/添え字演算子を使用できます。たとえば、次の抜粋では1
.
ただし、独自のプレースホルダー引数を定義すると、次のようになります。
ただし、飾らなくても問題なく動作します (次の出力は 7 です)。
(上記のように)添字演算子を使用しようとすると:
多くのエラーが発生します。要約すると、G++ 4.7.2 では、テンプレート引数の推論が失敗します。Clang 3.2 では、関数は配列型を返せないと言われました。
Phoenix プレースホルダー引数で添字演算子をサポートするにはどうすればよいですか?