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);
Related
I'm fairly new to C++, this is also my first post on here. I'm trying to use C++ in an embedded systems project so I can take the OOP approach. I'm using the AVR crosspack toolchain (AVR G++ compiler)
My problem is this:
From what i've read, the heap should not be used for dynamic memory allocation in embedded systems. In any case, there is no implementation for "new" in AVR G++ anyway. I'm using composition, starting with a USART driver (lets call it a service), and a logger (singleton pattern, and also a service).
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, however when I try to compose the objects needed in this way I get the following error:
Main/main.cpp: In function 'int main()':
Main/main.cpp:21:13: error: request for member 'log' in 'logSystem', which is of non-class type 'LogSystem(Usart)'
21 | logSystem.log("Hello");
| ^~~
make: *** [Main/main.o] Error 1
My sense is that my syntax for passing in an object as a constructor parameter is wrong, but I'm not sure what it should be as all the examples i can find use the "new" keyword in the constructor definition to create the object on the free store. Can anyone help?
The Code:
In "usart.h":
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
// Constructor and destructor
Usart();
~Usart();
// Initialisation routine
static void const init(void);
// Utility function to transmit a string
static void const print(const char myString[]);
};
In "logger.h":
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart usart);
~LogSystem();
Usart usart;
static void const log(char *msg);
};
In "logger.cpp"
#include "logger.h"
LogSystem::LogSystem(Usart usart)
{
Usart usart;
usart.init();
}
LogSystem::~LogSystem()
{
}
LogSystem::log(char *msg)
{
usart.print(msg);
}
In "main.cpp":
#include "logger.h"
int main()
{
LogSystem logSystem(Usart usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
[...] the heap should not be used for dynamic memory allocation in embedded systems.
It depends. I'm currently in an embedded project with maximum safety-related requirements, and we use new, but not delete. So we have a heap, but don't allocate "dynamically", because all allocated objects are kept during the runtime.
In any case, there is no implementation for "new" in AVR G++ anyway.
Is this true? I never checked... It might be necessary to provide a heap before being able to use new.
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, [...]
This is a good idea. ;-) It helps unit-testing.
For your syntactical and design problems: This is how I would write your sources.
"usart.h":
All methods are non-static to have access to member variables.
The const attribute on a return type is doing nothing. Did you mean to declare the method constant? Then const belongs after the parameter list. However, this attribute might be wrong if such a method changes any member variable.
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
Usart();
~Usart();
void init(void);
void print(const char myString[]);
};
"logger.h":
Just give and store a reference to the USART to avoid a copy.
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart& usart);
~LogSystem();
void log(const char *msg);
private:
Usart& _usart;
};
"logger.cpp"
The member variable _usart is directly initialized in the constructor, before any statement is executed.
#include "logger.h"
LogSystem::LogSystem(Usart& usart) : _usart(usart)
{
_usart.init();
}
LogSystem::~LogSystem()
{
}
void LogSystem::log(const char *msg)
{
_usart.print(msg);
}
"main.cpp":
Provide the USART object on the stack, as the logger.
#include "logger.h"
int main()
{
Usart usart;
LogSystem logSystem(usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
The singleton design pattern is deprecated since it was invented, because it is so hard to test. Simply use just one object or a limiting object factory.
I am using VS2019
Trying to call a thread in DLL. to run two executables simultaneously with detach
following threads worked when I Run a normal c++ program
I get error
Error C3867 'myClass::runexeone': non-standard syntax; use '&' to create a pointer to member myGateway C:\Users\user\Downloads\Demo\myGateway\myplugin.cpp 21
plugin header
#include <windows.h>
#include <iostream>
#include <thread>
#define MYPLUGIN_EXPORT __declspec(dllexport)
extern "C"
{
MYPLUGIN_EXPORT void WINAPI OnStart();
}
pluging.cpp
#include "plugin.h"
using namespace std;
class myClass
{
public:
myClass()
{
}
~myClass()
{
}
void onStart()
{
std::thread(runexeone).detach();
std::thread(runexetwo).detach();
}
void runexeone()
{
int exerunpne = system("cmd /C \"%MY_ROOT%\\bin\\Mytest.exe\" -ORBEndpoint iiop://localhost:12345 -d");
}
void runexetwo()
{
int exeruntwo = system("cmd /C \"%MY_ROOT%\\bin\\Mytest_2.exe\" -ORBEndpoint iiop://localhost:12345 -d");
}
};
myClass& getmyclass()
{
static myClass myclass;
return myclass;
}
MYPLUGIN_EXPORT void WINAPI OnStart()
{
getmyClass().onStart();
}
The problem is that runexeone is an unqualified name of a member function, and std::thread needs something executable. runexeone isn't. VC++ tries to guess from context what you mean, but the suggestion isn't enough. Even if you had written &myClass::runexeone, it still wouldn't have worked, because myClass::runexeone also needs a this pointer. You can fix the latter problem by making it static.
Compiler suggestions work best when there's just one problem.
As MSalters already mentioned, you provided the wrong data type for the functor for std::thread. If you cannot make the method static (which you can actually at least for the current state of your code, but to let this not be unstated here), you can do this
void onStart()
{
std::thread(std::bind(&myClass::runexeone, this)).detach();
}
But be careful about the lifetime/existence of your object/this!
Recently I ran into a compiler (GNU g++ 4.9.2) error like this:
ProceduralTimerTaskAdapter.cpp:25:13: error: pointer to member type ‘void (Poco::Util::Timer::)(Poco::Util::TimerTask&)’ incompatible with object type ‘Poco::Util::ProceduralTimerTaskAdapter’
Here is the relevant code (which is almost self-contained, save for the necessary Poco libs):
ProceduralTimerTaskAdapter.h:
#include <Poco/Util/Timer.h>
#include <Poco/Util/TimerTask.h>
#include <Poco/Util/TimerTaskAdapter.h>
#ifndef PROCEDURALTIMERTASKADAPTER_H
#define PROCEDURALTIMERTASKADAPTER_H
using namespace std;
using namespace Poco::Util;
typedef void (*Callback) (TimerTask&);
namespace Poco {
namespace Util {
class ProceduralTimerTaskAdapter : public TimerTaskAdapter <Timer> {
public:
ProceduralTimerTaskAdapter (Callback procedure); // Constructor
void run (); // Method defining the main thread
protected:
~ProceduralTimerTaskAdapter (); // Destructor (not for general use)
private:
ProceduralTimerTaskAdapter (); // Default constructor (not for general use)
Callback procedure; // The callback procedure called by the timer.
};
}
}
#endif
ProceduralTimerTaskAdapter.cpp:
// This is the implementation of the ProceduralTimerTaskAdapter class.
#include <iostream>
#include <Poco/Util/Timer.h>
#include <Poco/Util/TimerTask.h>
#include <Poco/Util/TimerTaskAdapter.h>
#include "ProceduralTimerTaskAdapter.h"
using namespace std;
using namespace Poco::Util;
ProceduralTimerTaskAdapter::ProceduralTimerTaskAdapter (Callback procedure) : TimerTaskAdapter<Timer>::TimerTaskAdapter (*(new Timer ()), procedure)
{
this -> procedure = procedure;
}
ProceduralTimerTaskAdapter::~ProceduralTimerTaskAdapter ()
{
}
void ProceduralTimerTaskAdapter::run ()
{
TimerTask &task = *this;
(this ->* procedure) (task);
}
What I wanna do is, in fact, build an extension of the well-known TimerTaskAdapter to handle callback functions, which are not tied to a specific class (because they are situated in main.cpp, for instance). I override the virtual method run () with a very simple self-made one, which calls the callback. After having handled several different errors, I ended up with this apparent class mismatch I can't solve myself. I even don't understand why the compiler states a class name, whose name is Poco::Util::Timer:: (Why does it end with ::?). As ProceduralTimerTaskAdapter defines a member named procedure, why does the compiler expect another class?
Thank you.
Derive from Poco::Util::TimerTask (like in Poco::Util::TimerTaskAdapter class) and override run method in which you will call procedures.
class ProcedureAdapter : public Poco::Util::TimerTask {
public:
typedef void (*Callback)(TimerTask&);
ProcedureAdapter (Callback c) : callback(c) {;}
void run () {
callback(*this); // call some procedure which takes TimerTask
}
Callback callback;
};
void fun (Poco::Util::TimerTask&) {
cout << "fun was invoked" << endl;
}
void fun2 (Poco::Util::TimerTask&) {
cout << "fun2 was invoked" << endl;
}
int main()
{
Poco::Util::Timer t;
t.schedule (new ProcedureAdapter{&fun},1,1);
t.schedule (new ProcedureAdapter{&fun2},1,1);
The syntax ->* expects a left-hand operator of type pointer to class object (such as this) and a right-hand operator of type pointer to member function of that class. But in
TimerTask &task = *this; // line 24
(this ->* procedure) (task); // line 25
procedure is not a pointer to a member function of ProceduralTimerTaskAdapter. So your code is ill-formed. procedure is simply a pointer to a free (non-member) function taking a TimerTask& and returning void. If ProceduralTimerTaskAdapter is derived from
TimerTask then the following code should compile
TimerTask &task = *this;
(this -> procedure) (task);
or shorter
procedure(*this);
using the fact that pointers to functions can syntactically be used like the function.
Edit. It appears (from your comments to another answer) that your code was ill-formed in yet another way, namely that ProceduralTimerTaskAdapter was not derived from TimerTask. Then, of course already line 24 (not just 25) should produce an error. It seems, therefore, that you didn't show us the precise same code as the one that created the error message, or not all the errors it causes.
I am trying to make functions repository. I have created four files:
Function.hpp, Function.cpp, FunctionsRepository.hpp, FunctionsRepository.cpp
I want to keep pointers to functions in vector of pointers.
//FunctionsRepository.hpp
#ifndef FUNCTIONSREPOSITORY_HPP
#define FUNCTIONSREPOSITORY_HPP
#include <vector>
using namespace std;
class FunctionsRepository {
private:
static vector<double *> pointerToFunctions;
public:
static void addFunction(double * wsk);
};
#endif
//FunctionRepository.cpp
#include "FunctionsRepository.hpp"
void FunctionsRepository::addFunction(double * wsk) {
pointerToFunctions.push_back(wsk);
}
//Functions.hpp
#ifndef FUNCTIONS_HPP
#define FUNCTOINS_HPP
#include "FunctionsRepository.hpp"
int constFunction(int numberOfVehicles);
void linearFunction();
void stepFunction();
#endif
//Funcctions.cpp
#include "Functions.hpp"
double constFunction(double numberOfVehicles){
return numberOfVehicles/2;
}
double (*funcConstant)(double) = constFunction;
//ERROR HERE
FunctionsRepository::addFunction(funcConstant);
I want to add new functions to program as easily as its possible and use it leater in other parts of program.
But I dont get it. Why i am getting this error. The addFunction() method is static, that means I can use it in other classes or parts of program. Vector is static to make sure that is the only one copy for whole program.
Use function wrapper. std::function can stores callable objects. So, your code will contain something like this:
class FunctionsRepository {
private:
// void() - function prototype
static std::vector<std::function<void()>> pointerToFunctions;
public:
static void addFunction(std::function<void()> wsk)
{
pointerToFunctions.push_back(wsk);
}
};
for more information consult official documentation: http://en.cppreference.com/w/cpp/utility/functional/function
I solved It. I received an error because I was calling the FunctionsRepository::addFunction(funcConstant); expression out of any scope. I just created new function to execute this command and thats all.
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);