我有一个函数:
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/