簡體   English   中英

關於C ++中std :: promise的錯誤

[英]Error about std::promise in C++

我試圖將我的類實例傳遞給線程,並從線程返回處理后的對象。 我搜索了C ++多線程,發現std :: promising可能會有所幫助。

但是,我一開始就陷入困境。 這是我的代碼:

void callerFunc()
{
    //...
    std::promise<DataWareHouse> data_chunks;    
    // DataWareHouse is my customized class
    //data_chunks has a vector<vector<double>> member variable
    std::thread(&run_thread,data_chunks);
    // ............
}

void run_thread(std::promise<DataWareHouse> data_chunks)
{
    // ... 
    vector<vector<double>> results;
    // ...
    data_chunks.set_value(results);
}

上面的代碼生成錯誤:

 `error C2248: 'std::promise<_Ty>::promise' : cannot access private member declared in class 'std::promise<_Ty>'`

我可以知道我在做什么以及如何解決嗎?

非常感謝。 :-)

您的第一個問題是您正在使用std::thread - std::thread是一個低級類,應在其上構建更高的抽象。 線程在C ++ 11中的C ++中是新標准化的,並且所有粗略部分都尚未提出。

在C ++ 11中使用線程的三種不同模式可能對您有用。

首先, std::async 其次, std::threadstd::packaged_task混合。 第三,處理原始的std::threadstd::promise

我將說明第三個級別,它是最低級別和最危險的級別,因為這是您所要求的。 我建議您看一下前兩個選項。

#include <future>
#include <vector>
#include <iostream>

typedef std::vector<double> DataWareHouse;

void run_thread(std::promise<DataWareHouse> data_chunks)
{
  DataWareHouse results;
  results.push_back( 3.14159 );
  data_chunks.set_value(results);
}

std::future<DataWareHouse> do_async_work()
{
  std::promise<DataWareHouse> data_chunks;  
  std::future<DataWareHouse> retval = data_chunks.get_future();
  // DataWareHouse is my customized class
  //data_chunks has a vector<vector<double>> member variable
  std::thread t = std::thread(&run_thread,std::move(data_chunks));
  t.detach(); // do this or seg fault
  return retval;
}

int main() {
  std::future<DataWareHouse> result = do_async_work();
  DataWareHouse vec = result.get(); // block and get the data
  for (double d: vec) {
    std::cout << d << "\n";
  }
}

現場例子

使用std::async ,您將具有一個返回DataWareHouse的函數,它將直接返回std::future<DataWareHouse>

使用std::packaged_task<> ,它將占用您的run_thread並將其轉換為可以執行的packaged_task ,並從中提取std::future

std::promise<>是不可復制的,並且在調用run_thread()您隱式地嘗試調用復制構造函數。 該錯誤消息告訴您,由於標記為私有,因此無法使用復制構造函數。

您需要通過引用傳遞一個承諾( std::promise<DataWareHouse> & )。 如果這是安全的callerFunc()保證不會返回,直到run_thread()完成與對象(否則你將使用到銷毀堆棧分配對象的引用,而我也沒有解釋為什么這是很糟糕)。

您正在嘗試通過值將承諾傳遞給線程; 但是您需要通過引用傳遞結果,以將結果返回給呼叫者的承諾。 std::promise無法復制,以防止發生此錯誤。

std::thread(&run_thread,std::ref(data_chunks));
                        ^^^^^^^^

void run_thread(std::promise<DataWareHouse> & data_chunks)
                                            ^

錯誤提示您無法復制std::promise ,您可以在此處執行以下操作:

void run_thread(std::promise<DataWareHouse> data_chunks)

和這里:

std::thread(&run_thread,data_chunks); // makes copy of data_chunks

您應該傳遞參考:

void run_thread(std::promise<DataWareHouse>& data_chunks);
//                                         ^

然后將std::reference_wrapper傳遞給線程,否則它也會嘗試復制promise。 這可以通過std::ref輕松完成:

std::thread(&run_thread, std::ref(data_chunks));
//                       ^^^^^^^^

顯然,在線程完成運行之前, data_chunks必須處於活動狀態,因此您必須在callerFunc()加入線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM