C++ 将输出流对象和其他参数传递给多个线程

C++ 将输出流对象和其他参数传递给多个线程,c++,multithreading,c++11,ofstream,C++,Multithreading,C++11,Ofstream,我试图使用C++11标准将多个参数传递给多个线程,其中一个参数是流对象 我想传递一个of stream对象,因为我希望每个线程都写入不同的输出文件 我以这种方式初始化线程和输出流: std::thread execution_threads[NUMBER_OF_THREADS]; // creating multiple empty threads std::ofstream output_files[NUMBER_OF_THREADS]; // Empty output streams //

我试图使用
C++11
标准将多个参数传递给多个线程,其中一个参数是流
对象

我想传递一个
of stream
对象,因为我希望每个线程都写入不同的输出文件

我以这种方式初始化线程和输出流:

std::thread execution_threads[NUMBER_OF_THREADS]; // creating multiple empty threads
std::ofstream output_files[NUMBER_OF_THREADS]; // Empty output streams
// Opening and initializing the output files
每个线程执行一个带有两个参数的函数:

void execution(int thread_id, std::ofstream& output_file)
所以我环顾四周,在
C++11
中读到,当一个函数
func
有多个参数
a,b,C,d
时,不需要使用
struct
,只需编写
std::thread t(func,a,b,C,d)就可以传递它们。所以我写了这个循环来启动线程:

for (int i = 0; i < utils::NUMBER_OF_THREADS; i++) {
    execution_threads[i] = std::thread(execution, i, output_files[i]);
}
通过这种方式,一切都很好,它编译后运行得很好。但我真的不明白为什么编译器告诉我,如果我使用另一个方法,我会尝试使用删除的复制构造函数


感谢您的帮助。

std::thread
存储其参数的副本。当您向它传递一个不可复制的对象,如
std::ofstream
时,它会抱怨

您有两个选择:

1) 不要存储
std::ofstream
对象的数组;只需让线程存储自己的流即可。在这种情况下,不需要复制流(只需移动即可):


这会给您带来与传递包含
std::ofstream&
的结构相同的所有权和生存期问题(毕竟,这就是
std::reference_wrapper
的全部内容)。由您来确保您的
输出\u文件
数组在您的所有线程都完成它之前仍然有效。

std::thread
存储其参数的副本。当您向它传递一个不可复制的对象,如
std::ofstream
时,它会抱怨

您有两个选择:

1) 不要存储
std::ofstream
对象的数组;只需让线程存储自己的流即可。在这种情况下,不需要复制流(只需移动即可):

这会给您带来与传递包含
std::ofstream&
的结构相同的所有权和生存期问题(毕竟,这就是
std::reference_wrapper
的全部内容)。由您来确保您的
输出\u文件
数组在所有线程都完成之前仍然有效

Call to implicitly-deleted copy constructor of
'typename decay<basic_ofstream<char, char_traits<char> > &>::type'
(aka 'std::__1::basic_ofstream<char, std::__1::char_traits<char> >')
// Struct definition
struct thread_input {
    int thread_id;
    std::ofstream& output_file;
};

// This is the function that now has only one argument
void execution(struct thread_input input)

// And this is the loop that launches the threads
for (int i = 0; i < utils::NUMBER_OF_THREADS; i++) {
    struct thread_input input = {i, output_files[i]};
    execution_threads[i] = std::thread(execution, input);
}

// join() functions for each thread and end of the program
for (int i = 0; i < utils::NUMBER_OF_THREADS; i++) {
    execution_threads[i] = std::thread(execution, i, std::ofstream{});
                                                   //^^^^^^^^^^^^^^^ anonymous temporary
}
for (int i = 0; i < utils::NUMBER_OF_THREADS; i++) {
    execution_threads[i] = std::thread(execution, i, std::ref(output_files[i]));
                                                   //^^^^^^^^ std::ref added
}