10

C ++ 11ラムダを使用してアプリケーションの開発を始めており、いくつかの型を関数ポインターに変換する必要があります。これはGCC4.6.0で完全に機能します。

void (* test)() = []()
{
    puts("Test!");
};

test();

私の問題は、ラムダ内で関数またはメソッドのローカル変数を使用する必要がある場合です。

const char * text = "test!";

void (* test)() = [&]()
{
    puts(text);
};

test();

G ++ 4.6.0は、キャストエラーコードを提供します。

main.cpp: In function 'void init(int)':
main.cpp:10:2: error: cannot convert 'main(int argc, char ** argv)::<lambda()>' to 'void (*)()' in initialization

自動を使用する場合、それは問題なく動作します:

const char * text = "Test!";

auto test = [&]()
{
    puts(text);
};

test();

私の質問は、 [&]を使用してラムダの型を作成するにはどうすればよいですか?私の場合、STL std :: functionを使用できません(プログラムがC ++ RTTIおよびEXCEPTIONSランタイムを使用していないため)。この問題を解決するための関数の簡単な実装がありますか?

4

4 に答える 4

10

STL std :: functionを使用できません(プログラムがC ++ RTTIおよびEXCEPTIONSランタイムを使用していないため)

次に、に相当する独自の記述が必要になる場合がありますstd::function

の型消去の通常の実装ではstd::function、ほとんどの機能にRTTIは必要ありません。通常の仮想関数呼び出しを通じて機能します。したがって、独自のバージョンを作成することは可能です。

実際、RTTIstd::function必要target_typeとするのは、関数と関数だけtargetです。これらは、世界で最も有用な関数ではありません。std::function使用している実装が通常のビジネスにRTTIを必要としないと仮定すると、これらの関数を呼び出さなくても使用できる可能性があります。

通常、例外処理を無効にすると、プログラムは単にシャットダウンし、throwステートメントに遭遇するとエラーになります。また、aが発行する例外のほとんどは、std::function回復できるようなものではないため(空の呼び出し、functionメモリ不足など)、おそらくそのまま使用できますstd::function

于 2012-06-12T14:14:38.573 に答える
9

関数ポインターに変換できるのは、キャプチャーのないラムダのみです。これは、この特定の場合のみのラムダの拡張です[*]。一般に、ラムダは関数オブジェクトであり、関数オブジェクトを関数に変換することはできません。

状態(キャプチャ)を持つラムダの代替手段はstd::function、プレーン関数ポインターではなくを使用することです。


[*]:状態を保持するラムダを関数ポインターに変換できる場合、状態はどこで維持されますか?(この特定のラムダの複数のインスタンスが存在する可能性があることに注意してください。各インスタンスには、個別に保守する必要がある独自の状態があります)

于 2012-06-12T14:00:29.723 に答える
6

前述のように、関数ポインターに変換できるのは何もキャプチャしないラムダのみです。

std :: functionのようなものを使用または記述したくない場合は、別の方法として、他の方法でキャプチャするものをパラメーターとして渡すこともできます。それらを保持するための構造体を作成することもできます。

#include <iostream>

struct captures { int x; };
int (*func)(captures *c) = [](captures *c){ return c->x; };

int main() {
    captures c = {10};

    std::cout << func(&c) << '\n';
}

もう1つの方法は、キャプチャを必要としないglobal / static / thread_local/constexpr変数を使用することです。

于 2012-06-12T18:06:12.927 に答える
2

使用できますstd::function。「ランタイム」は必要ありません。それ以外の場合は、ここで自分自身を実装する方法のスケッチを探してstd::functionください

于 2012-06-12T13:10:04.607 に答える