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

Ben*_* A. 29 c++ libstdc++ c++11

我使用新的c ++ 11 std::thread接口遇到了问题.
我无法弄清楚如何std::ostream将对a的引用传递给线程将执行的函数.

这是传递整数的示例(在gcc 4.6下按预期编译和工作):

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

int k = 10;
std::thread t(foo, k);
Run Code Online (Sandbox Code Playgroud)

但是当我尝试传递一个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);
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点,还是根本不可能?

注意:从编译错误看来它似乎来自一个已删除的构造函数...

Ker*_* SB 51

线程复制他们的论点(考虑一下,那就是正确的事).如果你想明确地引用一个引用,你必须用它包装std::ref(或者std::cref用于常量引用):

std::thread t(foo, std::ref(std::cout));
Run Code Online (Sandbox Code Playgroud)

(引用包装器是一个包含引用的值语义的包装器.也就是说,您可以复制包装器,并且所有副本将包含相同的引用.)

像往常一样,只要您引用的对象保持活动状态,此代码才是正确的.买者自负.

  • @JohnDibling:如果你是一个受虐狂,并且相信你的C中有太多的加号,是的. (21认同)
  • @Tomalak:我也没有说或暗示它确实如此. (7认同)
  • 对于记录,我不建议在一般情况下通过指针传递.我在评论中提到它的唯一原因是完整性.这并不重要,但在我评论之前我做了投票. (7认同)
  • 传递指针需要改变程序逻辑,我想大家都同意这一点. (4认同)