2012-04-08 21 views
11

私はこのコードを持っていて、私が達成したいことが可能かどうかわかりません。ラムダ関数をどのように使用できますか?

_acceptor.async_accept(
    _connections.back()->socket(), 
    [this](const boost::system::error_code& ec) 
    { 
     _connections.push_back(std::make_shared<TcpConnection>(_acceptor.get_io_service())); 
     _acceptor.async_accept(_connections.back()->socket(), this_lambda_function); 
    } 
); 

ソケットが受け入れられたら、ハンドラ(別名ラムダ関数)を再利用したいと思います。これは可能ですか?これを達成するより良い方法はありますか?

+0

+1非常に興味深い質問です。私はこれまで考えなかった。 – templatetypedef

+1

https://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/f1b3569c8aac0660?pli=1 – Anonymous

+0

質問には関係ありませんが、先頭のアンダースコア(および隣接する2つのアンダースコア)予約されており、アプリケーション識別子として使用すべきではありません。 – Marc

答えて

9

あなたが仲介者としてstd::function<>(または同様のもの)を使用して、自身にラムダのコピーを保存する必要があります。

std::function<void(const boost::system::error_code&)> func; 
func = [&func, this](const boost::system::error_code& ec) 
{ 
    _connections.push_back(std::make_shared<TcpConnection>(_acceptor.get_io_service())); 
    _acceptor.async_accept(_connections.back()->socket(), func); 
} 

_acceptor.async_accept(_connections.back()->socket(), func); 

しかし、あなたは唯一の参照でそれを行うことができます。値でキャプチャしようとすると、動作しません。これは、このようなラムダの使用を、参照によるキャプチャが理にかなっている用途に制限する必要があることを意味します。したがって、非同期関数が終了する前にこのスコープを離れると、そのスコープは破棄されます。

あなたの他の選択肢は、ラムダではなく適切なファンクタを作成することです。最終的に、ラムダはすべてを行うことはできません。

+0

私たちは 'auto'を使用できませんか? – balki

+0

@balki:いいえ。C/C++では、変数名を使用する式で変数を初期化することは正当です。しかし、式の型が決まるまで変数名に型がないので、 'auto'変数を扱うときはこれを止めます。 –

関連する問題