6

私は最近、インターネットでラムダ式について少し読んでいましたが、C++0x のラムダ式には、ラムダ式にのみバインドされる単一の型 (または型) がないように思われます。つまり、ラムダ式です。式は、テンプレート引数またはauto引数/変数のみに一致します。hereで説明されているように、何が起こるかというと、

ラムダをサポートするコンパイラは、ラムダ式ごとに一意の匿名ファンクター型を作成します

私の質問は、それは悪いことですか? ラムダ式のみに一致するキーワードを使用することは理にかなっていますか?たとえばlambda、次のように機能します

void f(std::function<int(int)> func)
{
     func(2);
}

template<typename T>
void g(T func)
{
     func(2);
}

void h(lambda func)
{
     func(2);
}

int main()
{
    int fpointer(int);
    struct { int operator()(int var) { return var; } } functor;

    f(fpointer); //ok (actually a linker error, but for the sake of example)
    f(functor); //ok
    f([](int var) { return var; }); //ok

    g(fpointer); //ok
    g(functor); //ok
    g([](int var) { return var; }); //ok

    h(fpointer); //error -- function pointer isn't a lambda expr
    h(functor); //error -- functor isn't a lambda expr
    h([](int var) { return var; }); //ok

    return 0;
}

正直なところ、これの有用性は実際にはわかりません (特に がautoラムダ式を受け入れるため、変数にラムダを割り当てることができる場合)。また、特定の 1 つのタイプだけにバインドすることはできません (他のすべてのタイプを除外して)。

本質的に、私の質問は、ラムダ式が匿名であっても問題ないかということです(ユーティリティの観点から-lambda型の欠如は私たちにいくつかの機能を奪いますか-そして哲学的に-ラムダ式が常に持っていることは本当に意味がありますか? 「タイプ」auto)?

4

2 に答える 2

11

ラムダは独立した型です。コード

void h(lambda func)
{
     func(2);
}

ラムダにはランタイム ポリモーフィズムがないため、意味がありません。ラムダは次と同等であることを思い出してください

struct unique_name
{
    return_type operator()(Arg1 a1, Arg2 a2, ... , Argn an)
    {
        code_inside_lambda;
    }
}

それ自体がユニークなタイプです。上記のコードは、次のように言うのと同じです

void h(class C)
{
     C(2);
}

これは、C が を持っていると保証しても意味がありませんoperator()。テンプレートが必要です:

template<typename T>
void g(T func)
{
     func(2);
}

int main()
{
    g([](int x){return x + 2;});
}
于 2009-09-29T18:24:58.870 に答える
3

関数に名前があるかどうかに基づいて関数の型を区別する理由はありません。ラムダ関数は単なる省略形であり、便利な関数を簡単に定義できます。名前があってもなくても、呼び出されたときの関数の動作は同じです。

このように考えてください。ソフトウェアの初期バージョンには、無名関数として定義された述語があります。時間が経つにつれて、要件はより複雑になり、述語もより複雑になります。おそらく、複数の場所から呼び出す必要があります。賢明なことは、名前付き関数を持つようにリファクタリングすることです。

呼び出された関数 (述語を呼び出す関数) がそれを気にする必要がある理由はありません。単純か複雑か、名前付きか無名か - それはまだ単なる述語関数です。

1 つの小さな問題はクロージャーの問題です。確認していませんが、少し運が良ければ、C++ はクロージャーとラムダを使用してネストされた名前付き関数を取得します。

于 2009-09-29T18:25:20.587 に答える