[英]C++11 std::thread giving error: no matching function to call std::thread::thread
I'm testing c++11 threads with this code, but when creating the thread, I'm having the error no matching function for call to 'std::thread::thread()' . 我正在用这段代码测试c ++ 11线程,但是在创建线程时,我遇到错误没有匹配函数来调用'std :: thread :: thread()' 。
It's like if there was something wrong with the function I'm giving to std::thread ctr, but I don't see how it's wrong. 这就像我给std :: thread ctr的函数有问题,但我不知道它是怎么回事。 It is incompleted, but it looks right to me:
它没有完成,但看起来对我来说:
Header: 标题:
#ifndef CONNECTION_H
#define CONNECTION_H
#include <thread>
#include <mysql++.h>
class Connection
{
public:
Connection(std::string mysqlUser, std::string mysqlPassword);
~Connection();
private:
std::string mysqlUser;
std::string mysqlPassword;
std::string mysqlIP;
int mysqlPort;
mysqlpp::Connection mysqlConnection;
std::thread connectionThread;
void threadLoop();
};
#endif // CONNECTION_H
Source: 资源:
#include "connection.h"
Connection::Connection(std::string mysqlUser, std::string mysqlPassword)
{
this->mysqlUser = mysqlUser;
this->mysqlPassword = mysqlPassword;
this->mysqlIP = "localhost"; //default
this->mysqlPort = 3306; //default
//Launch thread
std::thread connectionThread(threadLoop);
}
Connection::~Connection(){
mysqlConnection.disconnect();
}
void Connection::threadLoop(){
//Connect to mySQL database
mysqlConnection = new mysqlpp::Connection(false);
if(mysqlConnection.connect(NULL, mysqlIP.c_str(), mysqlUser.c_str(), mysqlPassword.c_str(), mysqlPort)){
std::string consulta = "SELECT * FROM 'Coordinates'";
mysqlpp::Query query = mysqlConnection.query(consulta);
mysqlpp::StoreQueryResult res = query.store();
query.reset();
}
while(true){
// Stuff
}
}
The problem is that threadLoop
is a member function, but there is no object for it to be applied to. 问题是
threadLoop
是一个成员函数,但没有对象可以应用于它。 Just guessing: 只是猜测:
std::thread connectionThread(&Connection::threadLoop, this);
But that's just the syntactic issue; 但那只是句法问题; there's a logic problem, too: that line creates a local object of type
std::thread
that goes away when the function returns. 还有一个逻辑问题:该行创建了一个
std::thread
类型的本地对象,当函数返回时它会消失。 Its destructor will call std::terminate()
because the thread has not been joined. 它的析构函数将调用
std::terminate()
因为该线程尚未连接。 Most likely, this was supposed to attach a thread to the connectionThread
member. 最有可能的是,这应该将一个线程附加到
connectionThread
成员。 To do that: 要做到这一点:
std::thread thr(threadLoop, this);
std::swap(thr, connectionThread);
Your code has two problems: 您的代码有两个问题:
std::thread
constructor std::thread
构造函数提供不完整的信息 std::thread
before it is joined with the main thread. std::thread
thread。 For the first problem, as Pete Becker suggests , you need to provide the object on which the function will be called, because the constructor for std::thread
has no other way to know it. 对于第一个问题,正如Pete Becker建议的那样 ,你需要提供调用函数的对象,因为
std::thread
的构造函数没有其他方法可以知道它。 Assuming that you want to call function threadLoop()
on the Connection
object you are constructing, you can do this: 假设您要在正在构建的
Connection
对象上调用函数threadLoop()
,您可以这样做:
//Launch thread
std::thread connectionThread(threadLoop, this);
Internally, the constructor will call this->threadLoop()
(where this
is the Connection*
parameter it received, not the std::thread
itself, of course). 在内部,构造函数将调用
this->threadLoop()
(其中this
是它收到的Connection*
参数,当然不是std::thread
本身)。 And you will be fine. 你会没事的。
The second problem is that your std::thread
is destroyed immediately after starting, without having joined it to the main thread: this will call terminate()
, which is not a good thing. 第二个问题是你的
std::thread
在启动后立即被销毁,而没有将它加入主线程:这将调用terminate()
,这不是一件好事。 Once again, Pete suggests a good alternative. Pete再次提出了一个很好的选择。 Replace the above code with this:
用以下代码替换上面的代码:
// Launch thread
std::thread thr(threadLoop, this);
std::swap(thr, connectionThread);
The situation before this code is as follows: 此代码之前的情况如下:
std::thread
object, connectionThread
, which does not really represent a thread std::thread
对象connectionThread
,它并不真正代表一个线程 After executing the first line of code: 执行第一行代码后:
connectionThread
connectionThread
std::thread
object thr
, which will be destroyed at the end of the Connection
constructor, causing a call to terminate()
because it is never joined to the main thread. std::thread
对象thr
表示的活动线程,它将在Connection
构造函数的末尾被销毁,导致对terminate()
的调用,因为它永远不会加入主线程。 Fortunately, the second line of code comes to the rescue. 幸运的是,第二行代码可以解决问题。 After executing it:
执行后:
std::thread
, thr
, which can be safely destroyed because it does not represent a real thread (so it is not joinable) std::thread
, thr
,它可以被安全地销毁,因为它不代表一个真正的线程(因此它不可连接) connectionThread
, an object that will not be destroyed as long as the Connection
object exists. connectionThread
表示的活动线程,只要Connection
对象存在,该对象就不会被销毁。 Now, the problem is that you want to join connectionThread
to the main thread before it is destroyed, but you also want to avoid blocking the main thread. 现在,问题是你希望在销毁之前将
connectionThread
加入主线程,但你也想避免阻塞主线程。 The right time to do this join is the latest possible time: when connectionThread
is about to be destroyed. 进行此连接的正确时间是最新的可能时间:即将销毁
connectionThread
。 And this happens at the destructor of Connection
. 这发生在
Connection
的析构函数中。 So we'll add a line to this destructor, this way: 所以我们将以这种方式为这个析构函数添加一行:
Connection::~Connection(){
mysqlConnection.disconnect();
connectionThread.join(); // Now connectionThread can be safely destroyed
}
Besides, this is the safest place to call join()
, because it ensures that you will never destroy an unjoined connectionThread
. 此外,这是调用
join()
最安全的地方,因为它确保您永远不会破坏未connectionThread
。 This is RAII in action; 这是RAII的行动; if you are not familiar with the concept of RAII (or RIIA, as it is sometimes called), you can find a lot of information about this very important concept in the web, including this site.
如果您不熟悉RAII(或RIIA,有时也称为)的概念,您可以在网络上找到有关这个非常重要概念的大量信息,包括本网站。
All this put together: creating a Connection
object will create a new thread; 所有这些放在一起:创建一个
Connection
对象将创建一个新线程; in this thread, a new database connection will be established and a query will be executed, while the main thread remains free for whatever other use (for instance, managing the GUI). 在这个线程中,将建立一个新的数据库连接并执行一个查询,而主线程保持空闲以用于任何其他用途(例如,管理GUI)。 When the
Connection
object is finally destroyed, the main thread will wait for the additional thread to finish (if necessary) and then normal execution will continue. 当
Connection
对象最终被销毁时,主线程将等待额外的线程完成(如果需要),然后正常执行将继续。 I hope this is what you wanted to accomplish with your code. 我希望这是你想用你的代码完成的。
As you may evince from cppreference , std::thread
's constructor expect some form of function; 正如你可以从cppreference中看到的那样,
std::thread
的构造函数期望某种形式的函数; you can pass it a free function, a static member function or one of these packed together with its arguments by means of std::bind
. 你可以通过
std::bind
传递一个自由函数,一个静态成员函数或其中一个与其参数打包在一起的函数。 In order to execute a non-static member function you should use std::mem_fn
to pass it together with the object it should be called on. 为了执行非静态成员函数,您应该使用
std::mem_fn
将它与应该调用的对象std::mem_fn
传递。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.