passing functor to boost::thread failed in visual studio 2010 [duplicate] - c++

This question already has answers here:
Why is there no call to the constructor? [duplicate]
(3 answers)
Closed 8 years ago.
This simple code won't compile:
#include <cstdio>
#include <boost/thread.hpp>
struct ftor{
void operator()(){ printf("Hello"); }
};
int main()
{
boost::thread th( ftor() );
th.join(); //<--- error C2228: left of '.join' must have class/struct/union
}
But, following code well compiled:
#include <cstdio>
#include <boost/thread.hpp>
struct ftor{
void operator()(){ printf("Hello"); }
};
int main()
{
ftor f;
boost::thread th( f );
th.join();
}
Q: What's problem with #1 code ?
I use visual studio 2010 .
Update:
codepade http://codepad.org/r5Aok406 shows more informative error:
Line 19: error: request for member 'join' in 'th', which is of non-class type 'mythread ()(ftor (*)())'

boost::thread th( ftor() );
th is declared as a function that returns boost::thread, and takes a function pointer ftor(*)() as input parameter.
To avoid this, either use C++11's new initialization syntax,
boost::thread th{ ftor() };
Or add a parathesis around the ftor().
boost::thread th( (ftor()) );
This is actually one of the well-known c++ glitches. The cause of this problem is for C compatibility.
struct TEST;
TEST a(); //well defined in c, a is a function that returns TEST
C++ has to be compatible with C, so Test a() must be a function, but not declare a as a TEST instance and call its default constructor!

Related

How do I run a member function on a thread? [duplicate]

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);

Error C2248 in MVSE12 with std::thread

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);

Threads in Constructor in C++ [duplicate]

This question already has answers here:
Start thread with member function
(5 answers)
Closed 6 years ago.
I'm trying to create threads in a constructor of a class that will run a couple of functions inside that class, I've tried this:
ServerLogic::ServerLogic(SOCKET sock)
{
this->sock = sock;
this->dispatchThread = new std::thread(this->dispatchMessage);
}
void ServerLogic::dispatchMessage(){
/*
* this function will handle the connetions with the clients
*/
char recievedMsg[1024];
int connectResult;
//receive data
while (true){
connectResult = recv(this->sock, recievedMsg, sizeof(recievedMsg), 0);
//in case everything good send to diagnose
if (connectResult != SOCKET_ERROR){
this->messagesToDiagnose.push(std::string(recievedMsg));
}
else{
/*
* destructor
*/
}
}
}
but it's giving me an errors:
'ServerLogic::dispatchMessage': function call missing argument list; use '&ServerLogic::dispatchMessage' to create a pointer to member.
IntelliSense: function "std::thread::thread(const std::thread &)" (declared at line 70 of "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\thread") cannot be referenced -- it is a deleted function.
I think that the error message is basically telling you what to do. Consider the following code (which is problematic, but just serves to illustrate the point):
#include <thread>
class foo
{
public:
foo()
{
std::thread(&foo::bar, this);
}
void bar()
{
}
};
int main()
{
foo f;
}
To specify a member function, use
std::thread(&foo::bar, this);

Attempt to std::thread throws compiler errors when attempting to call the target function [duplicate]

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.

Function pointer in c++ class [duplicate]

This question already has answers here:
get function member address
(2 answers)
Closed 8 years ago.
I am trying to use function pointer in a c++ class but got an error.
#include <cstdio>
#include <iostream>
using namespace std;
class abc{
public:
void hello(){
printf("Hello world\n");
}
abc(){
void (*hw)(void);
hw = &hello;
hw();
}
}
int main()
{
abc ab;
return 0;
}
Error
error: cannot convert ‘void (abc::*)()’ to ‘void (*)()’ in assignment
But the following code works for me which is in code base. Can anyone please help me to find out the difference?
void hello(){
printf("Hello world\n");
}
int main()
{
void (*hw)(void);
hw = &hello;
hw();
return 0;
}
Function pointers are (unfortunately) completely different from method pointers, as the error is trying to indicate. This is because the object that the method works on needs to be passed in somehow, which is what makes methods fundamentally different from functions in the first place (and obviously affects how the call is done through the pointer). Method pointers are not even always the same size (and can be significantly larger than a function pointer) when multiple/virtual inheritance comes into play.
You need to declare a method pointer, and call it on behalf of an object of the right type using one of the esoteric .* or ->* operators:
class abc {
public:
void hello(){
printf("Hello world\n");
}
abc() {
void (abc::*hw)();
hw = &abc::hello;
(this->*hw)(); // or (*this.*hw)()
}
}