私はc++11の機能機能をいじっています。私が奇妙だと思うことの1つは、ラムダ関数の型が実際にはfunction<>型ではないということです。さらに、ラムダは型推論メカニズムとうまく連携していないようです。
添付されているのは、2つの整数を加算するために関数の2つの引数を反転することをテストした小さな例です。(私が使用したコンパイラは、MinGWではgcc 4.6.2でした。)この例では、の型はaddInt_f
function <>を使用して明示的に定義されていますaddInt_l
が、はラムダであり、その型は。で型推論されauto
ます。
コードをコンパイルすると、flip
関数は明示的に型で定義されたバージョンのaddIntを受け入れることができますが、ラムダバージョンは受け入れることができず、次のようなエラーが発生します。
testCppBind.cpp:15:27: error: no matching function for call to 'flip(<lambda(int, int)>&)'
次の数行は、ラムダバージョン(および「raw」バージョン)が適切な関数<>型に明示的にキャストされている場合に受け入れることができることを示しています。
だから私の質問は:
そもそもラムダ関数に型がないのはなぜ
function<>
ですか?小さな例では、なぜ別のタイプではなくタイプとしてaddInt_l
持っていないのですか?関数型プログラミングの観点から、関数/関数オブジェクトとラムダの違いは何ですか?function<int (int,int)>
lambda
これら2つが異なっていなければならないという根本的な理由がある場合。ラムダはに変換できると聞きました
function<>
が、違います。これはC++11の設計上の問題/欠陥、実装上の問題ですか、それとも2つをそのまま区別することには利点がありますか?単独の型addInt_l
アノテーションは、関数のパラメーターと戻り型に関する十分な情報を提供しているようです。上記の明示的な型キャストを回避できるようにラムダを記述する方法はありますか?
前もって感謝します。
//-- testCppBind.cpp --
#include <functional>
using namespace std;
using namespace std::placeholders;
template <typename T1,typename T2, typename T3>
function<T3 (T2, T1)> flip(function<T3 (T1, T2)> f) { return bind(f,_2,_1);}
function<int (int,int)> addInt_f = [](int a,int b) -> int { return a + b;};
auto addInt_l = [](int a,int b) -> int { return a + b;};
int addInt0(int a, int b) { return a+b;}
int main() {
auto ff = flip(addInt_f); //ok
auto ff1 = flip(addInt_l); //not ok
auto ff2 = flip((function<int (int,int)>)addInt_l); //ok
auto ff3 = flip((function<int (int,int)>)addInt0); //ok
return 0;
}