6

無名関数がはるかに簡単にする問題を解決しようとしていますが、これが c++ で可能かどうか疑問に思っていました。

私がやりたいことは(本質的に)

template<typename T>
T DoSomething(T one, function<T(T)> dosomething)
{
    return one + dosomething(5);
}

void GetMyVal(...)
{
   DoSomething<int>(1, /*anonymous func here*/)
}

この例は、私がしなければならないことのために非常に単純化されています。C# では、p => p*5 を実行します。これが C++0x で簡単であることはわかっていますが、それを使用することはできません。私は、boost::lambda、またはboost::bindとboost::functionのプレースホルダーを組み合わせたもののいずれかでそれを行うことができるはずだと感じていますが、それを機能させることができないようです. 無理かもしれませんし、それもいいですが、無理なら答えてください。ありがとう。

編集: わかりました、int の単純なケースは正常に動作するようですが、より複雑な構造はどうでしょうか? それでは、試してみましょう

struct NumHolder
{
  int x;
}

template<typename T>
T DoSomething(T one, function<T(NumHolder)> dosomething)
{
    NumHolder temp;
    temp = 5
    return one + dosomething(temp);
}

void GetMyVal(...)
{
   DoSomething<int>(1, /*anonymous func here*/)
}

ここで、私の C# 式は p => p.temp * 5 の行に沿ったものになります。ブーストを使用して C++ でこれを行うことは可能ですか?

編集 2: OK、今私はただ興味があります:D ラムダ式内で関数を呼び出すにはどうすればよいですか? だから、私たちが持っているなら

int ChangeVal(int mult)
{
    return mult*5;
}

struct NumHolder
{
  int x;
}

template<typename T>
T DoSomething(T one, function<T(NumHolder)> dosomething)
{
    NumHolder temp;
    temp = 5
    return one + dosomething(temp);
}

void GetMyVal(...)
{
   DoSomething<int>(1, /*anonymous func here*/)
}

C# では、p => ChangeVal(p) を呼び出すことができます。C++ ラムダ式を使用した場合、構文はどのようになりますか?

4

3 に答える 3

5

Anders が回答で述べているように、boost::lambda は便利ですが、場合によってはコードが読みにくくなる可能性があります。したがって、匿名関数で何をしたいかによって異なります。

質問で言及したような単純なケースp => p * 5では、Lambda または Bind を使用するのが合理的であるように思えますが、

DoSomething(1, _1 * 5);

編集: 2 番目の例は、構文がすぐに冗長になる 1 つの領域にヒットします: メンバー (データまたは関数) アクセス。「ドット」演算子は C++ でオーバーロードできないため、バインド式を使用して引数から「x」を取得する必要があります。

DoSomething(1, bind(&NumHolder::x, _1) * 5);

または、Boost.Lambda では、オーバーロードされた ->* 演算子を使用します。

DoSomething(1, &_1->* &NumHolder::x * 5);

編集 2: OK、最後にもう一度 :) 最後の質問では、C# でそれを書きp => ChangeVal(p)ますChangeVal

ChangeVal が int を取り、無名関数に と同等の処理をさせたいとするとChangeVal(the_arg.x)、Boost.Lambda で次のように記述します。

DoSomething(1, bind(&ChangeVal, &_1->*&NumHolder::x));

またはBoost.Bindでこれを実行します(Lambdaでも動作します):

DoSomething(1, bind(&ChangeVal, bind(&NumHolder::x, _1));
于 2010-04-05T18:35:07.943 に答える
2

いいえ、簡単な方法で行うことはできません。boost :: lambdaは役に立ちますが、私の意見では、コードを使用するときにコードが読みにくいので、避けたいと思います。

p=>p*5C#と同等だと思いますが_1*5、簡単に見てきただけなのでわかりません。単純なものの場合は機能しますが、制御構造が必要になるとすぐに、命令ではなく機能ベースの制御構造の別のセットを使用する必要があります。これは通常のC++コードとは非常に異なるため、他の人がコードを読みにくくするため、使用する価値がないと自分で判断しました。

于 2010-04-05T18:23:30.020 に答える
0

boostはc++の構文を拡張しません。C++には無名関数はありません。

于 2010-04-05T18:24:14.853 に答える