Function/Method pointers Pushed to a Deque - c++

I am making a Queue for running functions. I put the functions that require being called into a std::deque<bool(*)()> Then I later on cycle through the deque calling each function and letting it run, sometimes even doing things based on the return.
The problem I am having is actually with regards to placing these functions inside of the deque.
I have this deque inside a class called A2_Game. I also have a class called Button.
My code resembles the following:
class Button
{
bool DoInput();
}
class A2_Game
{
std::deque<bool(*)()> Input_Functions;
bool EnterName()
}
A2_Game::OtherMethod()
{
Button* btn1 = new Button();
Input_Functions.push_back(&A2_Game::EnterName); //The compiler told me to do this and it still won't compile the line..
Input_Functions.push_back(btn1->DoInput);
//Loop
}
I cannot determine how to fix my compile errors. I suspect some of you may be able to just tell me outright what needs to be changed/done in order to get this to compile, by looking at what I've shown here. In case that is !true then here are the compile errors.
error C2664: 'std::deque<_Ty>::push_back' : cannot convert parameter 1 from 'bool (__thiscall A2_Game::* )(void)' to 'bool (__cdecl *const &)(void)'
error C3867: 'Button::Doinput': function call missing argument list; use '&Button::Doinput' to create a pointer to member

if you want to push back functions you can use std::function (or boost if your compiler doesn't support c++11)
std::deque<std::function<bool()> > function_list;
Button* btn1 = new Button();
function_list.push_back([this](){return EnterName();});
function_list.push_back([btn1](){return btn1->DoInput();});
make sure everything in the lambda is still going to be valid when you call it from the function_list.
EDIT:
boost equivalent
std::deque<boost::function<bool()> > function_list;
Button* btn1 = new Button();
function_list.push_back(boost::bind(&A2_Game::EnterName,this));
function_list.push_back(boost::bind(&Button::DoInput,btn1));

The problem is that the signature of the class methods don't match with the function signature bool (*)(). The signatures of the two methods are bool (Button::*)(); or bool (A2_Game::*)(); respectively. (The actual class to which the method belongs is part of its signature!)
The solution here is to use functors/function objects. Functors are wrapper objects around "callable elements" that are useful if you want to treat functions like objects (in a OOP sense). If you have boost at hand your code could look similar to this (code compiles):
#include <boost/function.hpp>
#include <deque>
class Button
{
public:
bool DoInput() { return true; }
};
class A2_Game
{
public:
typedef boost::function<bool()> Functor;
std::deque<Functor> Input_Functions;
bool EnterName() { return true; }
void OtherMethod();
};
void A2_Game::OtherMethod()
{
Button* btn1 = new Button();
Input_Functions.push_back(boost::bind(&A2_Game::EnterName, this));
Input_Functions.push_back(boost::bind(&Button::DoInput, btn1));
}
boost::bind combines a function pointer with the reference to an actual class instance and returns an function object of the same type as A2_Game::Functor.
Note that boost::function has been integrated into the C++11 standard (see here), so if your project supports C++11 simply use #include <functional> and std instead of boost namespaces.

Related

Pointer to function from another pointer

I'm new to c++ and I'm trying to make a generic switch (i.e. the device, not the C++ statement) that could be used to blink lights, turn beeps on and off, etc, in my Arduino project.
I could create a switchable interface and implement that in the classes that I want to "switch". But since I'm doing it as study purposes and I saw the pointer-to-functions ability in C++ (that is new to me since I come from C# and Java), I tough it would be a good opportunity to give it a try...
The problem is that I can pass the function in my code only if it's a local function but it won't work if I try to pass a function from another object like a led for example.
Some code to illustrate the problem. This is the switch.cpp, it recieves the On and Off functions in it's constructor and it has a update method that is called inside the loop method in the Arduino ino main class:
auto_switch.cpp
using switch_function = void(*)();
auto_switch::auto_switch(const switch_function on_function, const switch_function off_function, const int max_speed_count)
{
//sets all variables...
}
void auto_switch::update(const unsigned long millis)
{
//turn switch on and off...
}
And this is my ino file
ino file
#include <Arduino.h>
#include "led.h"
#include "auto_switch.h"
led* main_led;
auto_switch* led_switch;
int slow_speed;
//ugly code
void turn_led_on()
{
main_led->turn_on();
}
//ugly code
void turn_led_off()
{
main_led->turn_off();
}
void setup() {
main_led = new led(2, 3, 4, true, color::white);
//ugly code
led_switch = new auto_switch(turn_led_on, turn_led_off, 3);
slow_speed = led_switch->add_speed(100, 100, 3, 1000);
led_switch->set_active_speed(slow_speed);
led_switch->turn_on();
}
void loop() {
led_switch->update(millis());
}
It works but I had to make a local function (turn_led_on and turn_led_off) to be able to assign the inner functions as a parameter to the auto_switch constructor, the parts that I've wrote //ugly code
I wanted to do something like this, without the glue code in between:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
Is it possible? I've read something about static pointer to function and some std functions that help with that, if I get it right the glue code is necessary in this case so that the compiler can know where the functions are coming from I guess (from which object), but since the functions I need to call cannot be static I've discarded this option, and the std functions I believe it can't be used with the Arduino or could but shouldn't for performance limitations...
Anyway, does it make sense, can it be done using pointer to functions or should I create a interface or something different?
Before deciding how to do it, the qquestion is what do you want to do and why. Because, maybe there are better alternatives using simple C++ idioms.
Option 1: specialization with polymorphism
Do you want to specialize some functions of your switch, so instead of calling the function of the auto_switch you'd call dome more specialized ones ?
In this case you wouldn't do:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
but instead you would rely on polymorphism with virtual functions in the base class:
class auto_switch {
...
virtual void turn_on();
virtual void turn_off();
...
};
and write a specialized class for the leds:
class led_witch : public auto_switch {
...
void turn_on() override;
void turn_off() override;
...
};
In fact, the compiler will generate some function pointers behind the scene, but you don't have to care:
auto_switch s1=new auto_switch(...);
auto_switch s2=new led_switch(...); // no problem !!
s1->turn_on(); // calls auto_switch::turn_on()
s2->turn_on(); // calls led_switch::turn_on() since the real type of s2 is led_switch
But event if each object's behavior is dynamic on the the base of the real class of the object, the objects of the same class share a behavior that was predefined at compile time. If this is not ok, go to the next option.
Option 2: the member function pointer
The functions of another objects can only be invoked with that object at hand. So having a function pointer to a led function is not sufficient: you also need to know on which led it shall be applied.
This is why member function pointers are different and somewhat constraint: you can only invoke functions of class of your member function pointer. If polymorphism is sufficient (i.e. if derived class has a different implementation of a function already foreseen in the base classe) then you are lucky. If you want to use a function that only exists in the derived class and not in the base class, it won't compile.
Here a simplified version of auto_swith: I provide a function, but allso a pointer to the object on which the function has to be invoked:
class auto_switch{
void (led::*action)();
led *ld;
public:
auto_switch(void(led::*a)(), led*l) : action(a), ld(l) {}
void go () { (ld->*action)(); }
};
// usage:
auto_switch s(&led::turn_off, &l1);
s.go();
Online demo
Option 3 : the functional way (may that's what you're looking for ?)
Another variant would be to use the standard functional library to bind a member function and the object on which it shall be executed (as well as any need parameters):
class auto_switch{
std::function<void()> action;
public:
auto_switch(function<void()>a) : action(a) {}
void go () { action(); }
};
Here you can bind anything: any function of any class:
auto_switch s(bind(&led::turn_off, l1));
s.go();
auto_switch s2(bind(&blinking_led::blink, l2));
s2.go();
Online demo
Option 4 : command pattern
Now if you want to perform something on an object when you turn on and off the switch, but you need total flexibility, you can just implement the command pattern : this lets you execute anything on any object. And you don't even need a function pointer.

Function Pointer to Class Member Function Error

I'm creating a system that has 7 categories of data (thus, 7 different objects) that users can add, edit and delete from. To be more efficient, I made a utility class extending from that defines add, edit and delete functions more specific to the program. Because the user can input data in the Add function, I'm passing a class member function pointer into List's addObject class that inputs the data specific for that object. Thus, the List class adds the object and each class has a class member function for their specific variables.
I have this error in the addObject class:
Called object type 'bool (Product::*)()' is not a function or function pointer
it seems like the List class can't access the Product data. When I added #include "Product.h" in the head, the compiler sent many errors about double initialization of Product functions, which is very odd because ALL classes have #ifndef, #define and #endif at top and bottom respectfully.
Here's my code - I added what I think is important for understanding, so let me know if you need more to understand:
Main:
#include <list>
#include <iterator>
#include <algorithm>
#include "Product.h"
#include "List.h"
int main ()
{
bool (Product::*prodFunc) () = &Product::addProduct;
allProducts.addObject(allProducts.back(), prodFunc);
}
in the List Class:
template<class DT>
bool List<DT>::addObject(DT & previous, bool (DT::* func)())
{
bool success = true;
int newID = 1 + (previous.getID());
cout << "New ID: " << newID << endl;
previous.setID(newID);
func(); //Error here
return success;
}
Product's addProduct class:
bool Product::addProduct()
{
bool success = true;
cout << "Please enter the following for your new product:\n";
addItem();
return success;
}
I'm sure (or at least hope) it's something real simple that I'm missing. Thanks!
Assuming you want to call the member function on the previous parameter, the way you make such a call is like this:
(previous.*func)();
Or, because the syntax looks gnarly, most advise using std::invoke instead
std::invoke(func, previous);
Which will automatically deduce that func is a member function and should be called with previous
You can not pass a pointer to a non-static member function as a bare function; it must be called on some object of the class's type. The easy way to implement this is with std::bind.
auto prodFunc = std::bind(&Product::addProduct, &allProducts.back());
allProducts.addObject(allProducts.back(), &prodFunc);
Alternatively, you could declare Product::addProduct() as a static member function, in which case your code should function as intended. Looking at how you are using it, that may be what you actually want.

std::thread initialization constructor gives compile error

i'm working into a Visual Studio project (v120 Compiler) that uses std::thread to read from usb device aside from the GUI, and the function throws an error : "Error C2661 'std::thread::thread' : no overloaded function takes 3 arguments"
here's code:
class IOThread
{
public:
IOThread(DeviceHandler *handle) : _handle(handle)
~IOThread();
std::thread *getThread(ThreadType type);
template <typename T>
void execRead(std::list<T> *dataStack)
{
std::thread *thread = getThread(Read);
if (thread == NULL)
{
thread = new std::thread(&DeviceHandler::readFromBus, _handle, dataStack);
_threadPool.push_back(std::make_pair(Read, thread));
}
}
private:
DeviceHandler *_handle;
std::vector<std::pair<ThreadType, std::thread *>> _threadPool;
};
moreover, DeviceHandler is an abstraction class, which defines pure virtual readFromBus function, which prototype is the following
template <typename T>
void readFromBus(std::list<T> *dataStack) = 0;
I wish you not to have the same headache as i do while solving this mess...
Regards,
As explained in the comments your situation is the same is in this question. Because the method DeviceHandler::readFromBus() is templated arbitrarily many overloads can be generated. (They share the name but have different signatures).
Because of this the compiler cannot select the correct overload, hence the error message. You will need to tell the compiler which overload to use by a cast. (as this answer explains)
The following cast should do:
thread = new std::thread(
static_cast<void (DeviceHandler::*)(std::list<T> *)>(&DeviceHandler::readFromBus),
_handle, dataStack);
I tried to give a MVCE of the error, but i can't test if it compiles;
but here's the actual structure of classes using your cast
thread = new std::thread(
static_cast<void (DeviceHandler::*)(std::list<T> *)>(&DeviceHandler::readFromBus),
_handle, dataStack);
http://ideone.com/gVh1Du
EDIT: I solved the problem, the issue was the templated pure definition, which i replaced by a function that takes in parameters an abstract struct as follows
typedef struct s_dataStack
{
DataType type;
std::list<void *> stack;
} t_dataStack;
and then i cast any stack element with provided type in enum "datatype".
Thanks for the help given anyway, it led me to the origins of the issue.

vector of function pointers

I'm trying to code a Gameboy emulator and i would like to use a vector of function pointers to call the right function instead of doing a long switch statement.
For example if the program counter point to 0x00 (in memory), the first element of the vector is NOP so void NOP() is called;
but i can't figure how to call the functions.
Z80.h
#include <vector>
using namespace std;
class Z80;
typedef void (Z80::*function_t)();
class Z80
{
public:
vector<function_t> fmap;
...
...
};
Z80.cpp
Z80::Z80()
{
fmap = { &Z80::NOP, &Z80::LDBCnn, &Z80::LDBCmA};
}
void Z80::emulateCycle() {
opcode = memory.readByte(r.pc);
fmap[opcode](); <---ERROR
r.pc++;
}
void Z80::NOP() {
}
this is the error:
IntelliSense: expression preceding parentheses of apparent call must have (pointer-to-) function type
This expression:
fmap[opcode]
gives you a pointer to a member function. You can't just call that - it needs the class instance too. But you're actually calling it from a class method itself - so this is the instance you're looking for:
(this->*fmap[opcode])();
Note that if you want to avoid that bit of syntax and you're using C++11, you can change your fmap to instead be a vector of std::function<void()> and initialize it thusly:
fmap = { std::bind(&Z80::NOP, this), // or [this](){ this->NOP(); }
std::bind(&Z80::LDBCnn, this), // etc.
std::bind(&Z80::LDBCmA, this)};
That will let you actually do:
fmap[opcode]();
I'm not entirely sure that using function pointer in this case is particularly much better than for example a big switch statement.
However, the reason you can't call your member function is that you are not passing your object to the function.
You need this;
(this->*fmap[opcode])();
Another option is to use static/free function pointers, like this:
void (*function_t)(Z80& self);
and call it with:
fmap[opcode](this).
[Or use std::function and std::bind, which covers over the rather (intentionally, apparently) ugly syntax]

Pass any member function of any class as a Callback function

I'm working on a OpenGL menu which contains some buttons. I want to be able to associate an action (member function (with a fixed signature) of any class!) to a button which gets executed when the button is pressed. I can do it right now but only for one type. I want to be able to use any member function of any class for my callback.
Right now I'm doing it like this:
#define BUTTONCALLBACK(Func) bind1st( mem_fun( &ClassICanSupport::Func ), this )
I can then create a button like this:
Button* b = new Button("Bla", BUTTONCALLBACK(functionIWanttoCall));
The Callback function has the following signature:
void callback(Button* source);
When I press the button I can execute the callback function which I passed.
I had a look at boost::bind but I couldn't really find a way to tackle the problem. Furthermore all my classes are derived from a class Object so I thought about a void* which I could convert to the right class with some typeid hack but I was unable to get it working. At the end I always had the problem that I couldn't completly eliminate the class type of the callback function (which would be necessary to save the function pointer in my button class) and still being able to call the function.
Do you have any idea how to tackle this problem?
Don't use pointers, use boost::function together with boost::bind (or std::function and std::bind if C++0x), something like
// in Button class (or whatever signature you need)
Button(const std::string&, boost::function<void(Button*)> callback) // ...
// you can then use callback as a function
// in calling code
Button *b = new Button("..", boost::bind(&Class::func, this));
You should use a function<void(Button*)> object. These are run-time polymorphic and can be used with any object that supports void operator()(Button*). You can find one in Boost, TR1 and C++0x. boost::bind works well with these objects.
Well, the easiest way would be with virtual functions, if you don't want to pull in Boost or don't have access to C++0x.
#include <iostream>
// fwd declare
class Button;
class BtnCallbackBase{
public:
virtual void operator()(Button*) = 0;
};
template<class C>
class BtnCallback : public BtnCallbackBase{
private:
typedef void (C::*callback_func)(Button*);
C* _object;
callback_func _onclick;
public:
BtnCallback(C* obj, callback_func func)
: _object(obj)
, _onclick(func)
{}
virtual void operator()(Button* btn){
(_object->*_onclick)(btn);
}
};
class Button{
public:
Button()
: _onclick(0)
{}
void Click(){
if(_onclick != 0)
(*_onclick)(this);
}
template<class C>
void RegisterCallback(C* obj, void (C::*func)(Button*)){
// cleanup old callback, deleting null pointer is a noop
delete _onclick;
_onclick = new BtnCallback<C>(obj,func);
}
~Button(){
delete _onclick;
}
private:
BtnCallbackBase* _onclick;
};
class MyClass{
public:
void ExampleCallback(Button* btn){
std::cout << "Callback works!\n";
}
};
int main(){
Button btn;
MyClass test;
btn.RegisterCallback(&test, &MyClass::ExampleCallback);
btn.Click();
}
Full example on Ideone.
If you want a solution to your problem without using Boost library / without using new C++ features then one of the best choice is Generic Callbacks Dispatcher discussed by Danny Kalev / Herb Sutter.
http://www.gotw.ca/gotw/083.htm