我有一个可以创建 url 的类,以及一个线程,它向实例询问 url 并使用 curl 运行它们(线程由类的静态成员管理,实例被添加到列表中,等等,为了便于阅读而省略,因为这不是问题) .代码是通过 VS 远程开发用 g++12 和 std20 编译的。
class Downloader
{
public:
using ParseCb = std::function<bool(const std::string&)>;
//typedef bool (*ParseCb)(const std::string&);
private:
ParseCb parse_cb;
public:
Downloader(ParseCb);
virtual ~Downloader();
protected:
bool parse_data(const std::string&);
virtual const std::string get_url() = 0;
};
从这个类派生出其他几个,每个实现自己的
get_url()
(由工作线程调用,执行,并将内容返回到parse_data
)。他们用using Downloader::Downloader;
继承构造函数。
我的一个回调函数有以下声明:
bool parse_my_json(const std::string& json);
像这样使用:
DownloaderDerived dldr(parse_my_json);
Downloader::Downloader(ParseCb p) : parse_cb(p)
{
// ...
}
现在实施
parse_data
:
bool Downloader::parse_data(const std::string& data)
{
cout << "Parsing data: " << endl;
cout << data << endl; // prints properly
std::string xd = R"({"status":"ok","meta":{"count":1},"data":{"0":null}})";
return parse_cb(data); // segfault
//return parse_cb(xd); // segfault
//return parse_my_json(data); // works properly
}
仿函数发生以下段错误:
[Unknown/Just-In-Time compiled code]
> std::function<bool (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::operator()(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const(const std::function<bool(const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)> * const this, __args#0) Line 591 C++
Downloader::parse_data(Downloader * const this, const std::string & data) Line 82 C++
Downloader::downloader_callback(Server srv) Line 236 C++
std::__invoke_impl<void, void (*)(Server), Server>(void (*&)(Server) __f) Line 61 C++
std::__invoke<void (*)(Server), Server>(void (*&)(Server) __fn) Line 96 C++
std::thread::_Invoker<std::tuple<void (*)(Server), Server> >::_M_invoke<0ul, 1ul>(std::thread::_Invoker<std::tuple<void (*)(Server), Server> > * const this) Line 252 C++
std::thread::_Invoker<std::tuple<void (*)(Server), Server> >::operator()(std::thread::_Invoker<std::tuple<void (*)(Server), Server> > * const this) Line 259 C++
std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(Server), Server> > >::_M_run(std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(Server), Server> > > * const this) Line 210 C++
libstdc++.so.6![Unknown/Just-In-Time compiled code]
libc.so.6!start_thread(void * arg) Line 442 C
libc.so.6!clone3() Line 81 C++
在
std_function.h
:
如果我使用函数指针而不是仿函数,我会得到类似的段错误:
[Unknown/Just-In-Time compiled code]
> Downloader::parse_data(Downloader * const this, const std::string & data) Line 82 C++
Downloader::downloader_callback(Server srv) Line 236 C++
std::__invoke_impl<void, void (*)(Server), Server>(void (*&)(Server) __f) Line 61 C++
std::__invoke<void (*)(Server), Server>(void (*&)(Server) __fn) Line 96 C++
std::thread::_Invoker<std::tuple<void (*)(Server), Server> >::_M_invoke<0ul, 1ul>(std::thread::_Invoker<std::tuple<void (*)(Server), Server> > * const this) Line 252 C++
std::thread::_Invoker<std::tuple<void (*)(Server), Server> >::operator()(std::thread::_Invoker<std::tuple<void (*)(Server), Server> > * const this) Line 259 C++
std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(Server), Server> > >::_M_run(std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(Server), Server> > > * const this) Line 210 C++
libstdc++.so.6![Unknown/Just-In-Time compiled code]
libc.so.6!start_thread(void * arg) Line 442 C
libc.so.6!clone3() Line 81 C++
至于n.m.的问题,
this
是0x7ffff0000090
,this->parse_cb
是0x7ffff00db700
在函数指针和函子的情况下:
- parse_cb Downloader::ParseCb
+ std::_Maybe_unary_or_binary_function<bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> (base) std::_Maybe_unary_or_binary_function<bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> std::_Maybe_unary_or_binary_function<bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>
+ std::_Function_base (base) std::_Function_base std::_Function_base
_M_invoker 0x7ffff0078f10 std::function<bool(const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)>::_Invoker_type
对于仿函数,内部作用域变量是:
+ this {bool (std::_Any_data &, const std::_Any_data &, std::_Manager_operation)} 0x7ffff00d5490 const std::function<bool(const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)> * const
__args#0 -var-create: unable to create variable object
我不知道发生了什么。我使用函数指针/仿函数错了吗?我一直无法在一个较小的例子中重现它,这已经尽可能地简化了。跟转发有关系吗
const&
?