c++ - 为什么从这个函数创建线程时会出错?

标签 c++ multithreading c++11

我有一个函数:

void reader (std::istream *in, std::string& out)
{
    (*in) >> out;
}

我可以很容易地调用它:

reader(&std::cin, out);

std::function<void(std::istream*, std::string&)> r = reader;
r(&std::cin, out);

但是,一旦我尝试使用以下任一方法从该函数创建线程:

std::thread *reader = new std::thread(reader, &std::cin, out);

std::thread *reader = new std::thread(r, &std::cin, out);

我遇到了一些奇怪的错误:

/usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple<std::function<void(std::basic_istream<char>*, std::basic_string<char>&)>(std::basic_istream<char>*, std::basic_string<char>)>’: /usr/include/c++/4.8/thread:137:47:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with
_Callable = std::function<void(std::basic_istream<char>*, std::basic_string<char>&)>&; _Args = {std::basic_istream<char, std::char_traits<char> >*&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&}]’ asyncinput.cpp:39:56:   required from here /usr/include/c++/4.8/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<std::function<void(std::basic_istream<char>*, std::basic_string<char>&)>(std::basic_istream<char>*, std::basic_string<char>)>’
       typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                             ^ /usr/include/c++/4.8/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of<std::function<void(std::basic_istream<char>*, std::basic_string<char>&)>(std::basic_istream<char>*, std::basic_string<char>)>’
         _M_invoke(_Index_tuple<_Indices...>)

我曾尝试将函数转换为 lambda,但这没有帮助。我不知道我做错了什么。

最佳答案

错误信息很难解析,但这里有一个测试用例:

#include <sstream>
#include <string>
#include <thread>
#include <iostream>

void reader (std::istream* in, std::string& out)
{
    (*in) >> out;
}

int main()
{
    std::function<void(std::istream*, std::string&)> r = reader;
    std::istringstream ss("lol");
    std::string out;

    std::thread t(reader, &ss, out);
    t.join();
    std::cout << out << '\n';
}

( live demo )

问题是你正在传递 out,但是 std::thread 的参数被复制并且拷贝(临时)不能绑定(bind)到那个 std::string&

您必须明确表明您希望通过引用传递:

std::thread t(reader, &ss, std::ref(out));
//                         ^^^^^^^^^   ^

固定测试用例:

#include <sstream>
#include <string>
#include <thread>
#include <iostream>

void reader (std::istream* in, std::string& out)
{
    (*in) >> out;
}

int main()
{
    std::function<void(std::istream*, std::string&)> r = reader;
    std::istringstream ss("lol");
    std::string out;

    std::thread t(reader, &ss, std::ref(out));
    t.join();
    std::cout << out << '\n';
}

输出:

lol

( live demo )

(请注意,我从您的示例中删除了大量不必要的指针使用。)

或者,放弃整个事情并改用 lambda:

#include <sstream>
#include <string>
#include <thread>
#include <iostream>

int main()
{
    std::istringstream ss("lol");
    std::string out;

    std::thread t([&]() {
        ss >> out;
    });
    t.join();
    std::cout << out << '\n';
}

( live demo )

关于c++ - 为什么从这个函数创建线程时会出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27581751/

相关文章:

c++ - Borland Builder 2007 - 使 TForm 窗口透明

multithreading - Spark/EMR能否从s3多线程读取数据

android - AsyncTask ProgressDialog 不会更新对话框消息

java - AtomicInteger 的多线程不起作用

c++ - C++ 中具有可变参数签名的函数映射

c++ - 获取 C++0x 随机数生成器状态的标准方法是什么?

c++ - 使用 libsvn 获取树的最新版本

c++ - 如何在头文件c++中定义ofstream变量

c++ - 如何使用来自 int 值的数字符号初始化 char 数组?

c++ - 一个唯一的 ptr 类应该如何将它的实例指针传递给它的成员对象