3

誤解しないでください。Boostbind()は素晴らしいです。

しかし、私はそれを使ってコードを書いたり読んだりするのは嫌いであり、同僚がそれを悪用したり使用したりすることをあきらめました。

私は次のようなコードになります:

btn.clicked.connect(bind(&BetBar::placeBet, this, bet_id));
animator.eachFrame.connect(bind(&Widget::move, buttons[bet_id]));

これは論理的ではありますが、私がいいコードと呼ぶものとはかけ離れています。

実例を示すために...C++ 1xでは、次のようになります。

btn.clicked.connect([&](int bet_id){ placeBet(bet_id); })
animator.eachFrame.connect([&](Point newPos) { buttons[bet_id].move(newPos) })

そして、優れたDSLは次のようになります。

on(btn.clicked) placeBet(bet_id);
on(animator.eachFrame) buttons[bet_id].move(eachFrame::newPos);

C ++でのバインディングにどのように対処しますか?あなたはただあなたにどんな後押しを与えるかで生きていますか?

4

3 に答える 3

3

以下が欲しいようです。

  • への暗黙のバインディングthis
  • バインディングを格納する関数呼び出しに関連付けられた括弧の代替。
  • ラムダ式のどのパラメーターがバインドされているかを自動的に識別します。

1 つ目は、今日の C++ では非常に難しく、thisごく少数のコンテキストで暗黙的であり、暗黙的に関数に渡すことはできません。つまり、ライブラリ関数ではこれを達成できませんが、マクロでは可能です。それでも、それは醜いでしょう。

2 番目の部分ははるかに簡単です。

button.clicked.handler = bind(BetBar::placeBet, this, bet_id);

これはちょうど必要ですhandler.operator=(boost::function<void(*)()> const&)

3 番目は、2 フェーズの名前検索の別のケースを設計したばかりなので、やはり難しいです。それはテンプレートでは十分に困難でした。ブーストの _1 トリックは、後でバインドする引数を明示的にすることで機能します。ただし、_1 という名前は魔法ではありません。基本的には、boost::arg<1> を返す無料の関数です。したがって、animator.eachFrame.newPos の適切な定義により、以下を同等にすることができます。

animator.eachFrame.handler = bind(&Widget::move, buttons[bet_id], _1)
animator.eachFrame.handler = bind(&Widget::move, buttons[bet_id], animator.eachFrame.newPos)
于 2009-02-02T09:40:39.893 に答える
2

0x より前の C++ では、これよりもうまくいくとは思えません。Boost.Lambda や Phoenix は独自のバインド メカニズムを提供しますが、そのような場合は、実際には読みにくくなります。

boost::proto を使用して現在の C++ 内でそのような DSL をプログラムする方法を考えることができれば (他に代替手段はありますか?)、それなら、boost メーリング リスト自体の他の唯一のプロトガイによるより良い助けが得られるかもしれません。 、これは私の頭の上にあるので。

同僚の場合: 彼らが専門的に C++ プログラミングを行っている場合 (読み: 彼らはそれに対して報酬を得ています)、彼らはそれを理解するか、別の仕事をする必要があります。そのような単純な構造を読み取れない場合、新しい機能の実装を支援するよりも、メンテナンスの負担が大きくなる可能性があります。

そのような場合、Lua (または好みのスクリプト言語) に適切なバインディングを提供し、その言語でビジネス ロジックを実行させます。とにかく、これは実際にはそれほど悪い解決策ではありません。

于 2009-02-01T18:35:43.260 に答える
0

補足として、実際に優れた DSL は次のようになります。

btn.clicked { |bet_id| placeBet bet_id }
animator.eachFrame { |newPos| buttons[bet_id].move newPos }

あなたの質問に答えるには:単純な例では、プレーンなbind作品がうまくいきます。

于 2009-02-02T11:38:56.287 に答える