60692


現在、C++でRESTサーバを作成するのに以下のPistacheというOSSを利用しています。  
<https://github.com/oktal/pistache>

リクエストを受け付けると、画像をBase64に変換してJSONで応答したいと考え、以下を実装しました。  
期待するレスポンスは以下の通りです。  
itr->firstで キーを設定します。  
{  
"camera_1": base64でエンコードされた値,  
"camera_2": base64でエンコードされた値  
}

しかし、itr->first
は空になっており期待する結果となりません。これは、非同期のコールバックの処理が行われる頃にはitrは既に最後まで走査が終わってしまい、対応したitrの値を取得することが出来ないのだろうと想像していますが、具体的にどのように解決すればよいのか分かりません。教えて頂けないでしょうか？

[code]

    void ApiImpl::get_camera_image(Pistache::Http::ResponseWriter &response)
    {
        std::map<std::string, std::string> request_url{
            {"camera_1", "http://via.placeholder.com/600"},
            {"camera_2", "http://via.placeholder.com/300"}};
    
        std::vector<Async::Promise<Http::Response>> responses;
    
        std::string responce_body = "";
        nlohmann::json json_response;
        std::string base64;
    
        /* 全てのキーと値の走査 */
        for (auto itr = request_url.begin(); itr != request_url.end(); itr++)
        {
            auto resp = client->get(itr->second).send();
            resp.then(
                [&](Http::Response result) {
                    responce_body = result.body();
                    std::cout  << itr->first << std::endl;  /* 非同期処理のコールバック中で itr->first が空になっている */
                    base64 = Base64::Encode(result.body());
                    json_response[key] = base64;
                },
                [](exception_ptr &ptr) { std::cout << "An exception occured during user retrieval:" << std::endl; });
    
            /* 非同期のリクエストをPromiseの配列に追加 */
            responses.push_back(std::move(resp));
        }
    
        /* awaitに非同期のリクエストを登録する */
        auto sync = Async::whenAll(responses.begin(), responses.end());
    
        /* 以下はサンプルコードを参考にしたため完全に理解できていませんが、全部のPromiseの応答であるFutureを最大5秒待つと想定  */
        Async::Barrier<std::vector<Http::Response>> barrier(sync);
        barrier.wait_for(std::chrono::seconds(5));
    
        auto json_base64 = json_response.dump();
        response.headers().add<Pistache::Http::Header::ContentType>(MIME(Application, Json));
        response.send(Pistache::Http::Code::Ok, json_base64);
    } 
    
[/code]


CC BY-SA 4.0
2019-11-20T07:40:36.617
60690
2019-11-20T07:54:45.230
24811
question
c++ 非同期
非同期処理で値が保持されない

[code]

                [&](Http::Response result) {
    
[/code]

となっていて、[ラムダ式は参照によって暗黙にキャプチャ](https://ja.cppreference.com/w/cpp/language/lambda#Lambda_capture)します。しかしキャプチャしたはずの`itr`は`for`ループを抜けた時点で破棄済みなので正しくアクセスできません。`[=]`を使ってコピーを取得してはどうでしょうか？


CC BY-SA 4.0
2019-11-20T07:54:45.230
60692
2019-11-20T07:54:45.230
4236
60690
answer