为什么将对象引用参数传递给线程函数不能编译?

时间:2022-04-07 21:00:00

I've come to a problem using the new c++11 std::thread interface.
I can't figure out how to pass a reference to a std::ostream to the function that the thread will execute.

我在使用新的c++11 std:::thread接口时遇到了一个问题。我不知道如何将对std::ostream的引用传递到线程将要执行的函数。

Here's an example with passing an integer(compile and work as expected under gcc 4.6) :

这里有一个传递一个整数的例子(编译并按照gcc 4.6的要求工作):

void foo(int &i) {
    /** do something with i **/
    std::cout << i << std::endl;
}

int k = 10;
std::thread t(foo, k);

But when I try passing an ostream it does not compile :

但是当我尝试传递一个ostream时,它不会编译:

void foo(std::ostream &os) {
    /** do something with os **/
    os << "This should be printed to os" << std::endl;
}

std::thread t(foo, std::cout);

Is there a way to do just that, or is it not possible at all ??

有办法做到这一点吗?或者根本不可能?

NB: from the compile error it seems to come from a deleted constructor...

NB:从编译错误来看,它似乎来自一个已删除的构造函数……

2 个解决方案

#1


46  

Threads copy their arguments (think about it, that's The Right Thing). If you want a reference explicitly, you have to wrap it with std::ref (or std::cref for constant references):

线程复制它们的参数(想一想,这是正确的事情)。如果您想要显式引用,您必须使用std::ref(或std::cref,用于常量引用):

std::thread t(foo, std::ref(std::cout));

(The reference wrapper is a wrapper with value semantics around a reference. That is, you can copy the wrapper, and all copies will contain the same reference.)

引用包装器是围绕引用具有值语义的包装器。也就是说,您可以复制包装器,所有副本都将包含相同的引用。

As usual, this code is only correct as long as the object to which you refer remains alive. Caveat emptor.

通常,只要引用的对象保持活动状态,此代码就正确。购者自慎。

#2


-3  

void foo(intstd::ostream &os)

doesn't look like valid C++ to me.

看起来不像是有效的c++。

#1


46  

Threads copy their arguments (think about it, that's The Right Thing). If you want a reference explicitly, you have to wrap it with std::ref (or std::cref for constant references):

线程复制它们的参数(想一想,这是正确的事情)。如果您想要显式引用,您必须使用std::ref(或std::cref,用于常量引用):

std::thread t(foo, std::ref(std::cout));

(The reference wrapper is a wrapper with value semantics around a reference. That is, you can copy the wrapper, and all copies will contain the same reference.)

引用包装器是围绕引用具有值语义的包装器。也就是说,您可以复制包装器,所有副本都将包含相同的引用。

As usual, this code is only correct as long as the object to which you refer remains alive. Caveat emptor.

通常,只要引用的对象保持活动状态,此代码就正确。购者自慎。

#2


-3  

void foo(intstd::ostream &os)

doesn't look like valid C++ to me.

看起来不像是有效的c++。