0

次の例のBoostPhoenix式がコンパイルされることを期待します。

私は何が欠けていますか?

int plus(int a,int b)
{
    return a+b;
}

void main(int argc,char** argc)
{
    auto plus_1 = phx::bind(&plus,1,arg1);
    auto value  = phx::lambda[phx::val(plus_1)(arg1)]()(1);
    std::cout << value << std::endl;
}
4

3 に答える 3

4
auto plus_1 = phx::bind(&plus,1,arg1);

この行の後には、1 つの引数を取り、それに 1 を追加plus_1する関数オブジェクトがあります。int

phx::lambda[plus_1(arg1)](1);

おっと。(上で述べたように)は 1 つの引数を取り、それに 1 つ追加plus_1する関数オブジェクトであるため、これは機能しません。intここでは、 で呼び出そうとしていますarg1

コードからは、何を期待しているのかは明らかではありません。明確にできますか?

====編集====

質問のコードを編集したようです。あなたのコードはまだ間違っていますが、別の理由があります。これ:

phx::val(plus_1)(arg1)

... を使用valして、単項関数を返す nullary 関数を作成しますplus_1。次に、nullary 関数を で呼び出そうとしarg1ます。ブーム。

これは、実行して実行するコードです(私が信じていることです)。

#include <iostream>
#include <boost/phoenix/phoenix.hpp>
namespace phx = boost::phoenix;
using phx::arg_names::arg1;

int plus(int a,int b)
{
    return a+b;
}

int main()
{
    auto plus_1 = phx::bind(&plus, 1, arg1);
    int value = phx::bind(phx::lambda[plus_1], arg1)(1);
    std::cout << value << std::endl;
}

1 つ目bindはバイナリplusを受け取り、最初の引数が にバインドされた単項関数に変換し1ます。2 番目は、最初の と同等bindの新しい単項関数を作成しますが、これは を使用して最初の関数を安全にラップすることによって行われます。なぜそれが必要なのですか?以下のコードを検討してください。これは同等ですが、 はありません。lambdalambda

// Oops, wrong:
int value = phx::bind(phx::bind(&plus, 1, arg1), arg1)(1);

arg1が 2 回表示されることに注意してください。すべての式は、裏返しに評価されます。まず、内部を にバインドしてarg1から、内部のyielding を1評価し、それをバインドして呼び出します。呼び出し可能ではないため、機能しません。bind22

を使用するとlambda、内部のスコープが作成されるため、arg1熱心に置換されることはありません。しかし、私が言ったように、bindの必要性を強制する2 番目の を使用lambdaすると、最初の と同等の関数が得られます。したがって、それは不必要に複雑です。bindしかし、 、lambdaおよび Phoenix スコープについて理解するのに役立つかもしれません。

于 2012-09-29T02:01:19.410 に答える
2

ここで使用して何を達成しようとしているのかは明確ではありませんが、(結果として) でlambda呼び出したいだけの場合は、試みよりもはるかに簡単です:plus_112

#include <iostream>
#include <boost/phoenix.hpp>

int plus(int a, int b)
{
    return a + b;
}

int main()
{
    namespace phx = boost::phoenix;

    auto plus_1 = phx::bind(plus, 1, phx::arg_names::arg1);
    std::cout << plus_1(1) << '\n';
}

オンラインデモ

これが達成しようとしているものでない場合は、実際に何を望んでいるのかを説明する必要があります。:-]

于 2012-09-28T21:19:32.113 に答える
1

おそらくこれはそれをよりよく説明することができます。

フェニックスは魔法ではありません; それは何よりもまずC++です。したがって、C++のルールに従います。

phx::bindは、関数オブジェクトを返す関数です。これは、operator()バインドされた関数を呼び出すオーバーロードされたオブジェクトです。最初のステートメントは、このオブジェクトをに格納しますplus_1

これらすべてを考えると、式があるときはいつでもplus_1(...)、これは関数呼び出しです。それはそれです; そのオブジェクトの型でオーバーロードされた関数を呼び出し、operator()その関数にいくつかの値を渡すと言っています。

その式がaの真ん中にあるかどうかは関係ありませ[]ん。phx::lambdaC++にルールを変更させることはできません。即時の関数呼び出し以外はplus_1(...)もできません。また、すぐに関数を呼び出すこともできません。arg1plus_1(...)

于 2012-10-01T16:39:55.757 に答える