2

これは、boostasioの例に基づくboost:: asioudpechoデモです。

C ++ラムダを使用したこのバージョンの肉は、ブーストの例の半分未満のサイズですが、gccは、でreceived表示されないことを教えてくれますrecv_from

これをもっと冗長な方法で書かなければならないのは私にとって苦痛です。一部のC++の第一人者は、相互再帰的なラムダを定義するためのトリックを手伝ってくれますか?

class server {
public:
  server(io_service& io_service, short port)
    : socket_(io_service, udp::endpoint(udp::v4(), port)) {
    auto recv_from = [&,received]() {
      socket_.async_receive_from(buffer(data_, max_length), sender_endpoint_,
                                 received);
    };
    auto received = [&,recv_from](const error_code& error, size_t bytes_transferred) {
      if (!error && bytes_transferred > 0) {
        socket_.async_send_to(buffer(data_, bytes_transferred), sender_endpoint_,
                              [&](const error_code&, size_t) {
                                recv_from();
                              });
      } else {
        recv_from(); // loop
      }
    };
    recv_from();
  }

private:
  udp::socket socket_;
  udp::endpoint sender_endpoint_;
  enum { max_length = 1024 };
  char data_[max_length];
};

編集、解決策:これを追加する必要がありました:

std::function<void(const error_code&, size_t)> received;

型推論エンジンを簡単にするために(Haskellをプログラムしたのは甘やかされています)

Edit2:生涯の問題があるため、機能しません。

4

1 に答える 1

4

私自身の質問に答える:

実際、私のコードには少なくとも 3 つの問題があります。

  1. andを対応するクロージャーにコピーして、コンストラクターがスコープ外になったときに使用できるように注意しました。残念ながら、クロージャーはコンストラクターと同時にスコープ外になります。したがって、のコピーは意味がありません。receivedrecv_from[&, xxx]xxx

  2. 型推論エンジンを満足させるには、ラムダの少なくとも (?) 1 つの型を修正する必要があります。

  3. しかし、それでは問題 1 は解決しません。有効期間の問題を修正するには、オブジェクトにクロージャー オブジェクトを格納する必要がありましたserver

だから私はこれが私がする必要があることに近いと思います:

class server {
 public:
   server(io_service& io_service, short port)
     : socket_(io_service, udp::endpoint(udp::v4(), port)) {
    recv_from = [&]() {
       socket_.async_receive_from(buffer(data_, max_length), sender_endpoint_,
                                 received);
    };
    received = [&](const error_code& error, size_t bytes_transferred) {
      if (!error && bytes_transferred > 0) {
        socket_.async_send_to(buffer(data_, bytes_transferred), sender_endpoint_,
                              [&](const error_code&, size_t) {
                                recv_from();
                              });
      } else {
        recv_from(); // loop
      }
    };
    recv_from();
  }

private:
  udp::socket socket_;
  udp::endpoint sender_endpoint_;
  std::function<void(const error_code&, size_t)> received;
  std::function<void()> recv_from;
  enum { max_length = 1024 };
  char data_[max_length];
};
于 2013-03-13T20:20:19.793 に答える