我有一个功能:
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,但这没有帮助。我不知道我做错了什么。
答案 0 :(得分:4)
错误信息非常难以解析,但这是一个测试用例:
#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';
}
问题是您正在传递out
,但是std::thread
的参数被复制,副本(临时)不能绑定到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
(请注意,我已经从您的示例中删除了大量不必要的指针使用情况。)
或者,删除整个内容并改为使用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';
}