This question already has answers here:
Default value of function parameter
(5 answers)
Closed 3 years ago.
I'm getting a compile error when trying to use a method defined as having and option argument. The error message is this:
error: no matching function for call to 'ConsoleWidget::logInfo(const
char [32])'consoleWidget->logInfo("This is logging an info message");
Below are my files.
(header) .h
#ifndef CONSOLEWIDGET_H
#define CONSOLEWIDGET_H
#include <QTextEdit>
#include <QAction>
#include <QColor>
class ConsoleWidget : public QTextEdit
{
Q_OBJECT
public:
explicit ConsoleWidget(QWidget *parent = nullptr);
public slots:
void logInfo(const QString& text, const bool includeTimestamp /*=false*/);
};
#endif // CONSOLEWIDGET_H
cpp (.cpp)
void ConsoleWidget::logInfo(const QString &text, bool includeTimestamp = false)
{
...
}
(main) .cpp
auto *consoleWidget = new ConsoleWidget(this);
consoleWidget->logInfo("This is logging a message!");
A default argument is (secretly) evaluated and passed by the caller of the function, so it must be known where the function is called.
If the compiler has seen
void foo(int x = 37);
and then encounters
foo();
it will replace that with the equivalent of
foo(37);
If it has seen only void foo(int x);, there will not be a function with a matching prototype, because the function always takes an int parameter.
(This is different from, for instance, Python, where default arguments are evaluated when the function is defined and the calling code doesn't need to care.)
The solution is to move your default value from the function definition to its declaration.
Related
This question already has answers here:
Call constructor inside a call to another constructor
(2 answers)
Most vexing parse C++11
(2 answers)
Closed 7 months ago.
I have problem with C++ class. Is there have any way to reuse variable in the same class in the header file?
I have try
PubSubClient mqttClient(this->secureClient);
PubSubClient mqttClient(mqtt.secureClient);
but fail. Why?
#ifndef __MQTT_H_
#define __MQTT_H_
#include "Arduino.h"
#include "WiFi.h"
#include "WiFiClientSecure.h"
#include "PubSubClient.h"
class MQTT
{
public:
bool initWiFi();
String macAddress6btye(void);
void callback(char *topic, byte *payload, unsigned int length);
bool mqttConnect();
bool mqttPublish(const String &endPoint, const String &payload);
int getStrength(uint8_t points);
private:
WiFiClientSecure secureClient;
PubSubClient mqttClient(this->secureClient);
};
#endif
The declaration
PubSubClient mqttClient(this->secureClient);
is treated as a function declaration. An invalid one.
If you want to initialize the member variable (using other member variables), you need to do it with a constructor initializer list:
class MQTT
{
public:
MQTT()
: secureClient(),
mqttClient(secureClient) // Initialization here
{
// Empty function body
}
// ...
WiFiClientSecure secureClient;
PubSubClient mqttClient; // No initialization here
};
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);
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.
In class Foo I have two methods, assign_handler() and call_handler().
The actual handler code is in the main.cpp which is do_this(). do_this() uses the some global variables in main.cpp,
I think Foo has to have a function pointer as member which will be assigned in assign_handler() which is what I did. However I'm having trouble invoking assign_handler() i.e. calling do_this(), from call_handler().
Note: call_handler() itself is call by a sigaction in Foo.
EDIT: I tried producing a MCVE as suggested in the comments. I've used gedit to create the files and compile it using g++ in command line. The code works. However in my Eclipse project I get the errors shown in inline comments of the code.
MCVE:
//Foo.h
class Foo{
public:
void (*funptr)(void);
void call_handler();
void assign_handler (void(*func1)(void));
Foo(){};
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
funptr();//error: invalid use of member Foo::funptr in static member function; from this location
//or
//this->funptr();//error: 'this' is unavailable for static member functions
}
//main.cpp
#include <iostream>
#include "Foo.h"
using namespace std;
void do_this(void);
int main(void){
Foo foo;
foo.assign_handler(do_this);
foo.call_handler(); //this won't be called explicitly, it is assigned as a handler for a sigaction
int x;
cin>>x;
}
void do_this(void){
cout<<"done"<<endl;
}
I'll divide my answer in two parts. First I'll attempt to answer your question, then I'll attempt to tell you what you actually want to do.
Your question is how to assign a function pointer to a member variable and then call it from a static member function. Since the function pointer is a member of the class you will also require a pointer to the class in order to call the function pointer. A way of achieving this is to add a static member to your class that holds a pointer to the (single) instance of your class. Since you indicated that you will be using this as a signal handler, you won't want to use multiple handlers anyway.
So, something like this:
//Foo.h
class Foo{
public:
static void call_handler();
void assign_handler (void(*func1)(void));
Foo() {
ms_instance = this;
};
private:
void (*funptr)(void);
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
ms_instance->funptr();
}
A more general way would be to store a function object:
//Foo.h
#include <functional>
#include <utility>
class Foo{
public:
static void call_handler();
template<typename func>
void assign_handler (func&& handler)
{
m_handler = std::forward(handler);
}
Foo() {
ms_instance = this;
};
private:
std::function<void(void)> m_handler;
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::call_handler(){
ms_instance->m_handler();
}
This way you can assign lots of different stuff as the handler:
// Function pointers
foo.assign_handler(do_this);
// Lambdas
foo.assign_handler([]() { /* do something */ });
// Binds - you should probably prefer lambdas...
foo.assign_handler(std::bind(&MyClass::member_func, &myObj));
Now what you actually want to do when you are going to handle a signal is a bit more complicated. Remember that signal handlers can only call certain functions (async-signal-safe functions) - otherwise things may get ugly. Therefore there is a common trick that you should perform called the self pipe trick. Essentially you should have a signal handler that receives the signal, but only calls write on a pipe with the signal number as the data to send. Then you have another place in your code that calls select on the pipe and then read to read the signal number. You then call the appropriate handler function which is then allowed to do whatever you like.
An example of this is here: http://man7.org/tlpi/code/online/book/altio/self_pipe.c.html
Be aware that it can be slightly tricky to get this right in a cross-platform manner, especially if multithreaded.