Good evening everyone !
I am trying to code a multi-threaded application in C++ with Microsoft Visual Studio Express 2012.
The idea us that the "main" function call a thread which will run "forever", with the task of updating an object.
This is the main :
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <thread>
#include <iostream>//debug only
#include <fstream> //debug only
#include "dataCollectorFTL.h"
int _tmain(int argc, _TCHAR* argv[])
{
dataCollectorFTL dataCollector1;
//Launch thread which will run forever and get the data flows
dataCollector1.runDataCollector();
while(true){
//application running
}
return 0;
}
This is the ".h" of the class
#ifndef DATACOLLECTORFTL_H_INCLUDED
#define DATACOLLECTORFTL_H_INCLUDED
#include <thread>
class dataCollectorFTL {
public:
void runDataCollector();
void getData();
//constructor, destructor
dataCollectorFTL();
~dataCollectorFTL();
private:
HANDLE hProcess;
std::thread dataCollectorThread;
};
#endif // DATACOLLECTORFTL_H_INCLUDED
And finally the ".cpp"
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <thread>
#include "dataCollectorFTL.h"
void dataCollectorFTL::runDataCollector(){
//lauch a non-local thread
dataCollectorThread = std::thread(&dataCollectorFTL::getData, this);
}
void dataCollectorFTL::getData(){
//some stuff
}
dataCollectorFTL::dataCollectorFTL(){
//some stuff
}
dataCollectorFTL::~dataCollectorFTL(){
dataCollectorThread.join();
}
The problem is that when I run it, it gaves me this two errors :
Error 1 error C2248: 'std::thread::operator =' : cannot access private member declared in class 'std::thread' c:\users\damien\documents\visual studio 2012\projects\recherche\recherche\datacollectorftl.h 233 1 Recherche
Error 4 error C2248: 'std::thread::thread' : cannot access private member declared in class 'std::thread' c:\users\damien\documents\visual studio 2012\projects\recherche\recherche\datacollectorftl.h 233 1 Recherche
To save time, I can tell you that :
include in the .h doesn't change anything
The content of the runDataCollector methods doesn't change anything. Even if it is empty I still got the problem
std::thread dataCollectorThread can be public or private, it doesn't change anything
If I don't declare as a member of the class, I have a crash of the program because I don't join() the thread in runDataCollector(). And I don't want to join it, has getData() is a while(true) function where it gets data from another soft.
Thank you very much for the time you spent reading this, and thank you again for any help.
I understand that it was some time ago, but I bumped into the problem with same symptoms, and was able to solve it since my compilator (VC110 shipped with VS2012) was a little bit more verbose about what's the problem, so maybe it will help somebody.
I wanted to use this struct:
struct WorkerThreadContext
{
std::thread worker;
... some other attributes ...
}
in a std::vector. Build resulted in error message:
d:\code\testroom\t2\t2\t2.cpp(16): error C2248:
'std::thread::thread' : cannot access private member declared in class 'std::thread'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\thread(73) : see declaration of 'std::thread::thread'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\thread(32) : see declaration of 'std::thread'
This diagnostic occurred in the compiler generated function WorkerThreadContext::WorkerThreadContext(const WorkerThreadContext &)'
Key part is the last sentence - it seems that compiler has a problem to generate implicit copy constructor for my struct, so I changed it to:
struct WorkerThreadContext
{
std::thread worker;
... other attributes ...
WorkerThreadContext() {}
// added explicit copy constructor
WorkerThreadContext(const WorkerThreadContext&) {}
};
and was able to compile the code.
Edit: I almost forget. The reason why the compiler has a problem with this is, that std::thread objects cannot be copied (std::thread::operator=) so the compiler has a problem to construct implicit copy constructor, because it doesn't know how to copy the 'std::thread' object. Which also means, that if you put there explicit copy constructor as the one I wrote, your members (including the 'std::thread' one become invalid). You may (and you should) of course initialize the rest of the struct, however std::thread will remain uninitialized, because you cannot copy it.
When you pass a function in to the std::thread constructor, it needs to be callable from file-scope. In other words, if it's a member function, that function needs to be static. You can still pass in this - just tell the function to expect it.
In other words:
Add the following to the class declaration:
private:
void getData(); // Moved from public!
static void myGetData(DataCollectorFTL *ftl);
Write myGetData:
void DataCollectorFTL::myGetData(DataCollectorFTL *ftl) {
ftl->getData();
} // DataCollectorFLT::myGetData(ftl)
Change the call to std::thread()
//lauch a non-local thread
dataCollectorThread = std::thread(&myGetData, this);
Related
This question already has answers here:
Start thread with member function
(5 answers)
Closed 3 years ago.
When I compile the code below I get the following error. help me...!
Errors:
Error C2276 '&': illegal operation on bound member function expression
Error C3867 'CCore::Run': non - standard syntax; use '&' to create a pointer to member
I'm not sure if the program gives me an error.
I want to run the "Run" function of the Core class.
Core.cpp file contains only the functions created by the compiler.
I'm learning English so I'm not good yet. So please understand that the whole code.
// main.cpp
#include "Core.h"
#include <thread>
int main()
{
// The conditions below have been success
if (CCore::GetInstance().Init())
{
// The code below fails to compile.
// Error C3867 'CCore::Run': non - standard syntax; use '&' to create a pointer to member
thread main_thread(CCore::GetInstance().Run);
// Error C2276 '&': illegal operation on bound member function expression
thread main_thread(&CCore::GetInstance().Run);
main_thread.join();
}
return 0;
}
// Core.h
#pragma once
#include "Singleton.h"
#include <iostream>
using namespace std;
class CCore : public Singleton<CCore>
{
public:
CCore();
~CCore();
bool Init();
void Run();
};
// Singleton.h
#pragma once
template<typename T>
class Singleton
{
protected:
Singleton()=default;
~Singleton()=default;
public:
static T& GetInstance()
{
static T instance;
return instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton) = delete;
};
The compiler tells you the problem: Run() isn't a free function. It's a method, i.e. a function bound to an instance of an object. You have several options, but generally you either let the compiler synthesize a runnable for you, or write a free function yourself:
Let the compiler do all the work: guess what, it can make singletons for you so how cool is that?!
std::thread main_thread([]{
static CCore myCore;
myCore.Run();
});
You want to access that core? Sure!
std::future<CCore*> coreWhenDone = std::async([]{
static CCore myCore;
myCore.Run();
return &myCore;
});
Better yet, the core would provide some result, so that instead of accessing it directly when it's done, you could get its result (e.g. an int or std::vector<double> or whatever that core is computing)/
Let the compiler do some of the work:
std::thread main_thread([]{ CCore::GetInstance().Run(); });
Split the work between yourself and the compiler:
std::thread main_thread(std::bind(&CCore::Run, &CCore::GetInstance()));
Do all the work yourself:
void runCoreRun() {
CCore::GetInstance().Run();
}
...
std::thread main_thread(&runCoreRun);
This question comes from this question.
Im trying to implement the state pattern with a shared_ptr to the container(game).
However I have a problem with circular inclusion and need to forward declare.
My code:
Game.h
#pragma once
#include <memory>
#include "BaseState.h"
class Game : public std::enable_shared_from_this<Game>
{
private:
std::shared_ptr<BaseState> currentState;
public:
Game();
void switchState(std::shared_ptr<BaseState> nextState);
void doSomething(char);
void runState();
};
cpp
#include "stdafx.h"
#include <iostream>
#include "Game.h"
#include "SomeState.h"
Game::Game()
{
currentState = std::make_shared<SomeState>();
}
void Game::switchState(std::shared_ptr<BaseState> nextState)
{
currentState = nextState;
}
void Game::doSomething(char c)
{
std::cout << "Game : " << c;
}
void Game::runState()
{
currentState->handleCommand(shared_from_this());
}
BaseState.h
#pragma once
#include <memory>
#include "Game.h"
class BaseState
{
public:
virtual void handleCommand(std::shared_ptr<Game>) = 0;
};
SomeState.h
#pragma once
#include "BaseState.h"
class SomeState :
public BaseState
{
public:
// Inherited via BaseState
virtual void handleCommand(std::shared_ptr<Game>) override;
};
cpp
#include "stdafx.h"
#include "SomeState.h"
void SomeState::handleCommand(std::shared_ptr<Game> game)
{
game->doSomething('S');
}
I read other questions about forward declaring but still don't get it.
What I tried;
forward declare BaseState in Game, the code compiles but throws an error.
Unhandled exception at 0x73E9DAE8 in ConsoleApplication1.exe:
Microsoft C++ exception: std::bad_weak_ptr at memory location
0x00BBF5D4.
Forward declare Game in BaseState. Dosnt compile gives use of undefined type error, also
'doSomething': is not a member of
'std::shared_ptr'
which is logic because at compile time game has not a doSomething function because forward declared like;
class Game;
How do I decide where to forward declare another class, are there any logical steps or should I just pick one and fix the problems that choise creates?
You don't need to #include <Game.h> in BaseState.h, you can simply forward-declare it
class Game;
This works because the BaseState declaration doesn't need to know the contents of Game. So what you tried first is OK. The same applies to #include <BaseState.h> in Game.h. Replace that with a forward-declaration of BaseState.
The std::bad_weak_ptr exception was due to something else. Specifically, you're probably missing the little detail about shared_from_this, which says
It is permitted to call shared_from_this only on a previously shared
object, i.e. on an object managed by std::shared_ptr. Otherwise the
behavior is undefined
and
(from C++17) std::bad_weak_ptr is thrown (by the
shared_ptr constructor from a default-constructed weak_this)
You can usually solve this by instantiating your object into a shared_ptr:
int main() {
auto myGame = std::make_shared<Game>();
. . .
myGame->runState();
. . .
}
EDIT
Keep in mind though, that shared_ptr has a certain cost associated with using it. In general, if you know the pointed-to object always outlives the function call where it is used, as might be the case with your BaseState::handleCommand, then it may be faster (and still safe) to just pass it by reference.
I am new to Qt and trying to use QThread in a console application.
environment:
Qt Creator 3.6.1; Based on Qt5.6.0 (MSVC2013 32bit); build on Mar 14 2016; revision d502727b2c
What I did is:
Create a derived class QtThread inherit the QThread class
Create an std container vector and initialize few threads
using std::for_each to start all thread
Here is my question
First, In the class QtThread I have to implement copy constructor function otherwise, I will have compile error
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0:657: error: C2280: 'QtThread::QtThread(const QtThread &)': attempting to reference a deleted function
The reason I have to implement copy constructor here, I think, is the base class QThread has destructor ~QThread(). So the compiler will mark copy ctr and move ctr as delete. The derived class does not inherit copy/move ctr from base class.
Three issues regarding this.
In the main function, I use emplace_back(). It seems the compiler is using copy constructor instead move.Why~ (the std::thread is move only, unable to be copied, so the QThread can be copied is a bit strange to me, or maybe I did some wrong but I did not realize)
I can not use keyword default to let the compiler generating a copy ctr for me, why
QtThread(const QtThread &in_thread) = default; // not working, still having compile error C2280
The copy constructor I implemented is not good, it just create another thread and copies the name of the thread, seems not good to me, but I cannot find a better solution. Any suggestions?
The base class QThread does not have a virtual destructor. That seems unusual to me. That means derived class can not implicitly call QThread's destructor. Or maybe I am not supposed to inherit QThread at all?
Here is my code that declaring the QtThread:
#pragma once
#include <QtCore>
#include <QDebug>
#define qtout qDebug()
class QtThread : public QThread
class QtThread : public QThread
{
Q_OBJECT
public:
QtThread():QThread(nullptr){}
explicit QtThread(const QString &in_name);
// This copy constructor create a different thread with same name, bad
QtThread(const QtThread &in_thread) : QThread() { m_name = in_thread.m_name;} // have to implement copy constructor otherwise, the code will have error: C2280 compile error
//error: C2280: 'QtThread::QtThread(const QtThread &)': attempting to reference a deleted function
//QtThread(const QtThread &in_thread) = default;
void run();
QString m_name;
};
The cpp file
#include "qtthread.h"
QtThread::QtThread(const QString &in_name)
: QThread()
, m_name(in_name)
{}
void QtThread::run()
{
qtout << "QtThread" << m_name << "start to run";
for(int i = 0; i<1000; i++)
qtout << m_name << ": " << i;
}
Here is the main function
#include <QCoreApplication>
#include "qtthread.h"
#include <vector>
#include <algorithm>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::vector<QtThread> ts;
ts.emplace_back(QtThread("Tx"));
ts.emplace_back(QtThread("T5"));
ts.emplace_back(QtThread("T6"));
std::for_each(ts.begin(), ts.end(), [](QtThread &t){t.start();});
return a.exec();
}
Thanks for your time for reading the long post and helping me :)
[Edit 1]
Removed some experimental code from the main function.
Thanks for hyde and cod_fodder made the comments.
There is another detail thing I am wondering. The compiler requires me to overload the copy constructor for QtThread (otherwise compiler throws error CC2280). But what I am trying to do in the main function is move objects into the container. I know when the move operation failed, objects will be copied. In this case, Q_Object is not supposed to be copied, but what is the reason cause the QtThread object unable to be moved?
Thanks
In the blog woboq.com/blog/qthread-you-were-not-doing-so-wrong.html, it states that when event loop is needed, we could use worker/controller pattern, otherwise inherit QThread is good.
This question already has answers here:
Start thread with member function
(5 answers)
Closed 7 years ago.
Good afternoon,
I've been attempting to create a handful of threads to execute an update loop on some data, but when I attempt to call std::thread newThread(updateLoop), I get a generic compiler error for:
"No instance of constructor 'std::thread::thread' matches the argument list,"
and a MS VC++ 2015 error C3867:
"'projectileHandeler::updateLoop': non-standard syntax; use '&' to create a pointer to member"
When I attempt to follow the recommendation in C3867, changing the threading call to std::thread newThread(&updateLoop) the compiler throws MS VC++ C2276:
"'&': illegal operation on bound member function expression."
After reading the compiler error resources and trying variations such as std::thread newThread(this->updateLoop), std::thread newThread(*updateLoop), and std::thread newThread(*&updateLoop) [I was getting desperate then... I knew that last one wasn't going to work... ], I still get various errors relating to either an improper reference or my call the std::thread not matching the any overloads.
Could anyone please shed some light on my mistakes, please?
Of course, the code:
ProjectHandeler.cpp:
NB: The standard library thread and vector headers are included in stdafx.h
#include "stdafx.h"
#include "DataTypes.h"
#include "ProjectHandeler.h"
projectileHandeler::projectileHandeler(projectile* inputList[], int inputCount) {
for (int i = 0; i < inputCount; i++) {
projectileList.push_back(*inputList[i]);
}
//Create 1 thread for each 10 projectiles.
for (unsigned int i = 0; i < projectileList.size(); i++) {
std::thread thread(updateLoop);
thread.detach();
}
}
void projectileHandeler::updateLoop() {
//Do stuff
}
ProjectHandeler.h:
#pragma once
#ifndef PROJECTILE_H
#define PROJECTILE_H
#include "stdafx.h"
#include "DataTypes.h"
#endif
class projectileHandeler {
private:
std::vector<projectile> projectileList;
void updateLoop();
public:
projectileHandeler(projectile* inputList[], int inputCount);
~projectileHandeler();
projectile* getProjectilePointerFromId(unsigned int id);
//Make the NPC and Player handeler friend classes
};
Solution found... Although I still can't make the original version work, studying the post suggested by Niall had an obscure mention to using lambdas to preform the threading, which bypasses the need for member function references.
Therefore std::thread newThread(updateLoop); becomes std::thread([this] { updateLoop(); });
The later version also has the benefit of starting the thread anonymously,allowing the loop to execute with out having to rename anything.
That said, I would still appreciate an explanation to why the original code doesn't compile. After reading through it, I couldn't find an answer for the specific case here in the suggested duplicate post.
I want to write a static member function in my class CountInv, which should have only this static function and no other members
//Inversions.h
#ifndef INV_H
#define INV_H
#include <string>
#include <vector>
class CountInv
{
static void count();
}
#endif
//Inversions.cpp
#include "Inversions.h"
void CountInv::count() { return; };
I get the following compiler error :
Error 3 error C2556: 'CountInv CountInv::count(void)' :
overloaded function differs only by return type
from 'void CountInv::count(void)' d:\...\inversions.cpp 4
What is wrong? Nowhere have I declared or defined 'CountInv CountInv::count(void)' !! Should I write class c-tors,..,d-tors, or maybe some static data members to return from this function? but this should not be the issue..
Don't forget the closing semicolon ; after your class definition. That I think is causing the obscure compile error.
add ; to the end of class definition everything's goes fine!
I tried this on my local visual studio and adding semicoln in Inversions.h after class definition solves problem.
Thanks
Niraj Rathi