Before I present the code which is found at the bottom of this post I would like to talk about the issue and the fix's that I do not desire. Okay basically I've created a GUI from scratch sort of and one requirement I wanted for this was allow components to have their own click executions so if i click a button or tab etc.. It would call Component->Execute(); Well normally you would do something like a switch statement of ids and if that components ID equaled n number then it would perform this action. Well that seemed kinda dumb to me and I thought there has to be a better way. I eventually tried to incorporate a feature in JAVA where you would do like Component.AddActionListener(new ActionListener( public void execute(ActionEvent ae) { })); or something like that and I thought that this feature has to be possible in C++. I eventually came across storing void functions into a variable in which could be executed at any time and modified at any time. However I hadn't noticed an issue and that was this only worked with static functions. So below you'll see my problem. I've patched the problem by using a pointer to SomeClass however this would mean having an individual function call for every class type is there no way to store a function callback to a non-static class member without doing the below strategy? and instead doing a strategy like the commented out code?
//Main.cpp
#include <iostream> //system requires this.
#include "SomeClass.h"
void DoSomething1(void)
{
std::cout << "We Called Static DoSomething1\n";
}
void DoSomething2(void)
{
std::cout << "We Called Static DoSomething2\n";
}
int main()
{
void (*function_call2)(SomeClass*);
void (*function_call)() = DoSomething1; //This works No Problems!
function_call(); //Will Call the DoSomething1(void);
function_call = DoSomething2; //This works No Problems!
function_call(); //Will Call the DoSomething2(void);
SomeClass *some = new SomeClass(); //Create a SomeClass pointer;
function_call = SomeClass::DoSomething3; //Static SomeClass::DoSomething3();
function_call(); //Will Call the SomeClass::DoSomething3(void);
//function_call = some->DoSomething4; //Non-Static SomeClass::DoSomething4 gives an error.
//function_call(); //Not used because of error above.
function_call2 = SomeClass::DoSomething5; //Store the SomeClass::DoSomething(SomeClass* some);
function_call2(some); //Call out SomeClass::DoSomething5 which calls on SomeClass::DoSomething4's non static member.
system("pause");
return 0;
}
//SomeClass.hpp
#pragma once
#include <iostream>
class SomeClass
{
public:
SomeClass();
~SomeClass();
public:
static void DoSomething3(void);
void DoSomething4(void);
static void DoSomething5(SomeClass* some);
};
//SomeClass.cpp
#include "SomeClass.h"
SomeClass::SomeClass(void)
{
}
SomeClass::~SomeClass(void)
{
}
void SomeClass::DoSomething3(void)
{
std::cout << "We Called Static DoSomething3\n";
}
void SomeClass::DoSomething4(void)
{
std::cout << "We Called Non-Static DoSomething4\n";
}
void SomeClass::DoSomething5(SomeClass *some)
{
some->DoSomething4();
}
Secondary Fix for what I'll do not an exact answer I wanted but it meets my needs for now along with allowing additional features which would have become overly complicate had this not existed.
//Component.hpp
#pragma once
#include <iostream>
#include <windows.h>
#include <d3dx9.h>
#include <d3d9.h>
#include "Constants.hpp"
#include "ScreenState.hpp"
#include "ComponentType.hpp"
using namespace std;
class Component
{
static void EMPTY(void) { }
static void EMPTY(int i) { }
public:
Component(void)
{
callback = EMPTY;
callback2 = EMPTY;
callback_id = -1;
}
Component* SetFunction(void (*callback)())
{
this->callback = callback;
return this;
}
Component* SetFunction(void (*callback2)(int), int id)
{
this->callback_id = id;
this->callback2 = callback2;
return this;
}
void execute(void)
{
callback();
callback2(callback_id);
}
}
The syntax for pointers-to-member-functions is as follows:
struct Foo
{
void bar(int, int);
void zip(int, int);
};
Foo x;
void (Foo::*p)(int, int) = &Foo::bar; // pointer
(x.*p)(1, 2); // invocation
p = &Foo::zip;
(x.*p)(3, 4); // invocation
Mind the additional parentheses in the function invocation, which is needed to get the correct operator precedence. The member-dereference operator is .* (and there's also ->* from an instance pointer).
Related
I need help with passing a function pointer on C++. I can't linkage one function for a class to other function. I will explain. Anyway I will put a code resume of my program, it is much larger than the code expose here but for more easier I put only the part I need to it works fine.
I have one class (MainSystem) and inside I have an object pointer to the other class (ComCamera). The last class is a SocketServer, and I want when the socket received any data, it sends to the linkage function to MainSystem.
ComCamera is a resource Shared with more class and I need to associate the functions ComCamera::vRecvData to a MainSystem::vRecvData or other function of other class for the call when receive data and send de data to the function class associate.
Can Anyone help to me?
EDDITED - SOLUTION BELOW
main.cpp
#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <cmath>
#include <string.h>
#include <stdio.h>
#include <exception>
#include <unistd.h>
using std::string;
class ComCamera {
public:
std::function<void(int, std::string)> vRecvData;
void vLinkRecvFunction(std::function<void(int, std::string)> vCallBack) {
this->vRecvData = vCallBack;
}
void vCallFromCamera() {
this->vRecvData(4, "Example");
};
};
class MainSystem {
private:
ComCamera *xComCamera;
public:
MainSystem(ComCamera *xComCamera) {
this->xComCamera = xComCamera;
this->xComCamera->vLinkRecvFunction([this](int iChannelNumber, std::string sData) {vRecvData(iChannelNumber, sData); });
}
void vRecvData(int iNumber, string sData) {
std::cout << "RECV Data From Camera(" + std::to_string(iNumber) + "): " << sData << std::endl;
};
};
int main(void) {
ComCamera xComCamera;
MainSystem xMainSystem(&xComCamera);
xComCamera.vCallFromCamera();
return 0;
}
Output will be:
MainSystem RECV Data From Camera(4): Example
You can have ComCamera::vRecvData be of type std::function<void(int, std::string)> and then have ComCamera::vLinkRecvFunction() be like this:
void ComCamera::vLinkRecvFunction(std::function<void(int, std::string)> callBack)
{
this->vRecvData = callBack;
}
and have MainSystem constructor be like this:
MainSystem::MainSystem(ComCamera *xComCamera)
{
using namespace std::placeholders;
this->xComCamera = xComCamera;
this->xComCamera->vLinkRecvFunction([this](int iNumber, std::string sData){vRecvData(number, sData);});
}
Still though the original question has way too much code to go through friend.
Here what you want :
#include<iostream>
using std::cout;
class A; //forward declare A
class B{
public:
void (A::*ptr)(int x); //Only declare the pointer because A is not yet defined.
};
class A{
public:
void increase_by(int x){
a+=x;
} // this function will be pointed by B's ptr
int a = 0; // assume some data in a;
B b; // creating B inside of A;
void analyze(int y){
(*this.*(b.ptr))(y);
} // Some function that analyzes the data of A or B; Here this just increments A::a through B's ptr
};
int main(){
A a; // creates A
cout<<a.a<<"\n"; // shows initial value of a
a.b.ptr = &A::increase_by; // defines the ptr that lies inside of b which inturns lies inside a
a.analyze(3); // calls the initialize method
(a.*(a.b.ptr))(3); // directly calls b.ptr to change a.a
cout<<a.a; // shows the value after analyzing
return 0;
}
Output will be :
0
6
I still don't get why would you do something like this. But maybe this is what you wanted as per your comments.
To know more read this wonderful PDF.
I have a bit of trouble understanding a std::bind call.
In the following example:
#include <functional>
#include <iostream>
#include <memory>
class Notifier
{
public:
Notifier(std::function<void(Notifier&)> on_notify)
:on_notify_(on_notify)
{ }
void notify()
{
if (on_notify_)
on_notify_(*this);
}
std::function<void(Notifier&)> on_notify_;
};
struct Manager
{
Manager()
{
n_ = std::make_unique<Notifier>(std::bind(&Manager::trigger, this));
}
void trigger()
{
std::cout << "notified" << std::endl;
}
std::unique_ptr<Notifier> n_;
};
int main()
{
Manager s;
s.n_->notify();
}
I don't understand how on_notify_(*this); calls back the functor with a Notifier& parameter, but the functor created by bind doesn't specify it.
The calls result correctly to the void notify() method, but I don't understand what exactly will be the functor created by bind to result in this.
If I were to write a lambda instead, I would need to specify the parameter, otherwise it would compile.
What kind of operation does bind here behind my back? :-)
std::bind basically ignores the invalid given argument according to this.
If some of the arguments that are supplied in the call to g() are not matched by any placeholders stored in g, the unused arguments are evaluated and discarded.
It might surprise you that when even more absurd arguments are provided, the binded functor can still successfully reach Manager::trigger() as follows:
#include <functional>
#include <iostream>
#include <memory>
// Some classes that have nothing to do with on_notify_
class AAA {};
class BBB {};
class Notifier
{
public:
Notifier(std::function<void(AAA&, BBB&)> on_notify)
:on_notify_(on_notify)
{ }
void notify()
{
if (on_notify_)
{
// Arguments not matching.
AAA a{};
BBB b{};
// Invoke with them.
on_notify_(a, b);
}
}
std::function<void(AAA&, BBB&)> on_notify_;
};
struct Manager
{
Manager()
{
n_ = std::make_unique<Notifier>(std::bind(&Manager::trigger, this));
}
void trigger()
{
std::cout << "it's also notified!" << std::endl;
}
std::unique_ptr<Notifier> n_;
};
int main()
{
Manager s;
s.n_->notify();
}
Live demo is here.
I'd like to be able to write my ISR in one place:
some_collection TimerHandlers;
// added to ISR table in linker script
void rawTimerIRQHandler() {
call_each_handler_in(handlers);
}
Such that I can then register handlers in other files
// file1.cpp
void ledTimerHandler1() {
}
register(ledTimerHandler1); //or in an init function if not possible here
// file2.cpp
void ledTimerHandler2() {
}
register(ledTimerHandler2); //or in an init function if not possible here
And when the hardware jumps to rawTimerIRQHandler, it executes ledTimerHandler1 and ledTimerHandler2 in some arbitrary order.
Obviously, I can implement this using something similar to a vector<void(*)()>, but since the number of these handlers is known at compile-time, is there any way I can generate an array (or template linked list) at compile-time? I'd like to avoid the dynamic memory allocation that comes with vector.
I'm open to using template<>, #define, or even GCC-specific attributes to acheive this goal.
The scaffolding's a bit tedious but once it's done the usage couldn't be simpler:
// example.h:
#include "Registered.h"
struct example : Registered<example> {};
// main.cc:
#include <iostream>
#include "example.h"
int main ()
{
for ( auto p = example::registry; p; p=p->chain )
std::cout << p << '\n';
}
// Registered.h :
template<class registered>
struct Registered {
static registered *registry;
registered *chain;
Registered() : chain(registry) {registry=static_cast<registered*>(this);}
};
// example.cc:
#include "example.h"
template<> example *Registered<example>::registry = 0;
static struct example first, second, third; // these can be defined anywhere w/ static duration
edit: moved the first,second,third declaration/definitions to satisfy my inner pedant
Absolutley. If I understand correctly, you just want a fixed array of function pointers to your handlers. Using C++11 syntax, and assuming 3 handlers just for the sake of the example,
#include <array>
const std::array<HandlerPtr, 3> handlers= {&ledTimerHandler1, &ledTimerHandler2, &ledTimerHandler3};
or using more classic C/C++ syntax
const HandlerPtr handlers[] = {&ledTimerHandler1, &ledTimerHandler2, &ledTimerHandler3};
Based off jthill's answer, here's what I'll probably end up using (since I don't need a generic form):
struct timer_handler {
static timer_handler *first = 0;
timer_handler *next;
void (*f)();
public:
timer_handler(void (*f)()) : next(first), f(f) { first = this;}
// connect this to the interrupt vector
static inline void executeAll() {
auto p = first;
while(p) {
p->f();
p = p->next;
}
}
};
//a.cpp
void foo() {
}
timer_handler tfoo = foo;
//b.cpp
void bar() {
}
timer_handler tbar = bar;
I have the following problem. I have a function from an external library (which cannot be modified) like this:
void externalFunction(int n, void udf(double*) );
I would like to pass as the udf function above a function member of an existing class. Please look at the following code:
// External function (tipically from an external library)
void externalFunction(int n, void udf(double*) )
{
// do something
}
// User Defined Function (UDF)
void myUDF(double* a)
{
// do something
}
// Class containing the User Defined Function (UDF)
class myClass
{
public:
void classUDF(double* a)
{
// do something...
};
};
int main()
{
int n=1;
// The UDF to be supplied is myUDF
externalFunction(n, myUDF);
// The UDF is the classUDF member function of a myClass object
myClass myClassObj;
externalFunction(n, myClassObj.classUDF); // ERROR!!
}
I cannot declare the classUDF member function as a static function, so the last line of the code above results in a compilation error!
This is impossible to do - in c++, you must use either a free function, or a static member function, or (in c++11) a lambda without capture to get a function pointer.
GCC allows you to create nested function which could do what you want, but only in C. It uses so-called trampolines to do that (basically small pieces of dynamically generated code). It would be possible to use this feature, but only if you split some of the code calling externalFunction to a separate C module.
Another possibility would be generating code at runtime eg. using libjit.
So if you're fine with non-reenrant function, create a global/static variable which will point to this and use it in your static function.
class myClass
{
public:
static myClass* callback_this;
static void classUDF(double* a)
{
callback_this.realUDF(a);
};
};
Its really horrible code, but I'm afraid you're out of luck with such a bad design as your externalFunction.
You can use Boost bind or TR1 bind (on recent compilers);;
externalFunction(n, boost::bind(&myClass::classUDF, boost::ref(myClassObj)));
Unfortunately, I lived in a pipe dream for the last 10 minutes. The only way forward is to call the target using some kind of a static wrapper function. The other answers have various neat (compiler-specific) tidbits on that, but here's the main trick:
void externalFunction(int n, void (*udf)(double*) )
{ double x; udf(&x); }
myClass myClassObj;
void wrapper(double* d) { myClassObj.classUDF(d); }
int main()
{
externalFunction(1, &wrapper);
}
std::function<>
Store a bound function in a variable like this:
std::function<void(double*)> stored = std::bind(&myClass::classUDF, boost::ref(myClassObj))
(assuming C++0x support in compiler now. I'm sure Boost has a boost::function<> somewhere)
Vanilla C++ pointers-to-member-function
Without magic like that, you'd need pointer-to-memberfunction syntax:
See also live on http://ideone.com/Ld7It
Edit to clarify to the commenters, obviously this only works iff you have control over the definition of externalFunction. This is in direct response to the /broken/ snippet int the OP.
struct myClass
{
void classUDF(double* a) { };
};
void externalFunction(int n, void (myClass::*udf)(double*) )
{
myClass myClassObj;
double x;
(myClassObj.*udf)(&x);
}
int main()
{
externalFunction(1, &myClass::classUDF);
}
C++98 idiomatic solution
// mem_fun_ref example
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
int main ()
{
std::vector<std::string> numbers;
// populate vector:
numbers.push_back("one");
numbers.push_back("two");
numbers.push_back("three");
numbers.push_back("four");
numbers.push_back("five");
std::vector <int> lengths (numbers.size());
std::transform (numbers.begin(), numbers.end(), lengths.begin(),
std::mem_fun_ref(&std::string::length));
for (int i=0; i<5; i++) {
std::cout << numbers[i] << " has " << lengths[i] << " letters.\n";
}
return 0;
}
Here is how I do this, when MyClass is a singleton:
void externalFunction(int n, void udf(double) );
class MyClass
{
public:
static MyClass* m_this;
MyClass(){ m_this = this; }
static void mycallback(double* x){ m_this->myrealcallback(x); }
void myrealcallback(double* x);
}
int main()
{
MyClass myClass;
externalFunction(0, MyClass::mycallback);
}
#include <boost/bind.hpp>
#include <iostream>
using namespace std;
using boost::bind;
class A {
public:
void print(string &s) {
cout << s.c_str() << endl;
}
};
typedef void (*callback)();
class B {
public:
void set_callback(callback cb) {
m_cb = cb;
}
void do_callback() {
m_cb();
}
private:
callback m_cb;
};
void main() {
A a;
B b;
string s("message");
b.set_callback(bind(A::print, &a, s));
b.do_callback();
}
So what I'm trying to do is to have the print method of A stream "message" to cout when b's callback is activated. I'm getting an unexpected number of arguments error from msvc10. I'm sure this is super noob basic and I'm sorry in advance.
replace typedef void (*callback)(); with typedef boost::function<void()> callback;
A bound function doesn't produce an ordinary function, so you cannot just store it in a regular function pointer. However, boost::function is able to handle anything as long as it is callable with the correct signature, so that's what you want. It will work with a function pointer, or a functor created with bind.
After a few corrections to your code, I came up with this:
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
// i prefer explicit namespaces, but that's a matter of preference
class A {
public:
// prefer const refs to regular refs unless you need to modify the argument!
void print(const std::string &s) {
// no need for .c_str() here, cout knows how to output a std::string just fine :-)
std::cout << s << std::endl;
}
};
// holds any arity 0 callable "thing" which returns void
typedef boost::function<void()> callback;
class B {
public:
void set_callback(callback cb) {
m_cb = cb;
}
void do_callback() {
m_cb();
}
private:
callback m_cb;
};
void regular_function() {
std::cout << "regular!" << std::endl;
}
// the return type for main is int, never anything else
// however, in c++, you may omit the "return 0;" from main (and only main)
// which will have the same effect as if you had a "return 0;" as the last line
// of main
int main() {
A a;
B b;
std::string s("message");
// you forget the "&" here before A::print!
b.set_callback(boost::bind(&A::print, &a, s));
b.do_callback();
// this will work for regular function pointers too, yay!
b.set_callback(regular_function);
b.do_callback();
}