I have a class that uses a preexisting library. There is a function call that needs a function pointer, and I am trying to pass in the function that is in my class. It doesn't compile though. What can I do to fix this? (Also, I'm sure this was asked before in a much clearer way. I'm out of my element with this, so my apologies).
Note: This is for an arduino.
In my main program I have the following code...
#include "CM.h"
CM cm;
void setup() {
cm.setup();
}
CM.h
class CM {
private:
LibClass *lib;
void onInit();
public:
void setup();
};
CM.cpp
#include "CM.h"
void CM::setup() {
lib->attach(onInit); // <-- this isn't working.
}
void CM::onInit() {
Serial.println("HERE I AM");
}
To pass a member function, you need to make it "static" and then pass it with a full scope qualifier:
#include <iostream>
void attach( void (*func)(void) );
class CM {
private:
static void onInit();
public:
void setup();
};
void CM::setup()
{
attach(CM::onInit);
}
void CM::onInit(void)
{
std::cout << "HERE I AM";
}
// a global function pointer for this example
void (*p_func)(void);
// a "library" attach function
void attach( void (*func)(void) )
{
p_func = func;
}
int main(int argc, const char * argv[]) {
CM my;
my.setup();
p_func(); // like the library call
return 0;
}
Related
I am trying to add items to a map that is a private variable in a class based on if certain parameters are met. When I try to use the insert function for std::map or the [] operator, nothing happens. I don't even get an error. During debugging the code executes like everything is fine but the map stays empty.
I have tried multiple ways to insert to the map including the [] operator and different insert arguments.
class foo {
private:
std::map<std::string, int> map;
public:
void bar();
};
In cpp file:
void foo::bar() {
if(condition)
map.insert(std::make_pair("string", 1));
}
There are no error messages or warnings in the compiler or during debugging.
If the basic STD map usage works, maybe the problem sits in your condition implementation
#include <iostream>
#include <map>
class Foo {
std::map<std::string, int> map;
public:
void bar();
void print();
};
void Foo::bar() {
// if (condition) // weird condition causing failure
map.insert(std::make_pair("string", 1));
}
void Foo::print() {
std::cout << map.size() << std::endl;
std::cout << map.at("string") << std::endl;
}
int main(void) {
Foo foo;
foo.bar();
foo.print();
}
I want to create a std::function object for the parent class's version of a virtual and overridden function, see the following example:
#include <iostream>
#include <functional>
class Parent
{
public:
virtual void func1()
{
std::cout << "Parent::func1\n";
}
virtual void func2()
{
std::cout << "Parent::func2\n";
}
};
class Child : public Parent
{
public:
// overrides Parent::func1
virtual void func1()
{
std::cout << "Child::func1, ";
Parent::func1();
}
// overrides Parent::func2
virtual void func2()
{
std::cout << "Child::func2, ";
std::function< void() > parent_func2 = std::bind( &Parent::func2, this );
parent_func2();
}
};
int main()
{
Child child;
child.func1(); // output: Child::func1, Parent::func1
child.func2(); // output: Child::func2, Child::func2, ...
return 0;
}
While the call to child.func1() behaves as expected, the call to child.func2() becomes an infinite recursion, where parent_func2() seems to call Child::func2() instead of Parent::func2() to which I intended to bind it.
Any idea how I can have parent_func2() really call Parent::func2?
You can do it by writing a small functor:
struct Parent_func2
{
void operator()( Parent* p ) const
{
p->Parent::func2();
}
};
And use
std::function< void() > parent_func2 = std::bind( Parent_func2(), this );
(thinking about it, I guess this is just a more verbose way of what Xeo suggested. #Xeo, make your comment an answer and you have my upvote...)
In trying to shorted my code for readability, I wound up changing too much and making mistakes. This is still condensed but taken straight from my code.
My problem is that I have a class called "function" and a derived class "pwfunction" which both have the virtual () operator. I'd like to pass an array of pointers to my "function" objects to various actual functions and use the () operator.
Final edit: This is a SSCCE version of what I'm talking about.
#include <iostream>
using namespace std;
class function
{
public:
virtual double operator () (double x) {return 1.5;}
};
class pwfunction : public function
{
public:
virtual double operator() (double x) {return 2.0;}
};
void interface();
void definefuncs (function** funcs, long unsigned numfuncs);
void interpolate(function* infunc);
void solvefuncs(function** funcs, long unsigned numfuncs);
int main()
{
interface();
return 0;
}
void interface()
{
long unsigned numfuncs = 1;
function* funcs[numfuncs];
definefuncs(funcs, numfuncs);
solvefuncs(funcs, numfuncs);
}
void definefuncs (function** funcs, long unsigned numfuncs)
{
interpolate(funcs[0]);
}
void interpolate(function* infunc)
{
infunc = new pwfunction();
cout<< (*infunc)(1.5)<<endl; //works
}
void solvefuncs(function** funcs, long unsigned numfuncs)
{
cout<< (*funcs[0])(1.5); //Error Message: Segmentation fault
}
The problem comes from the following:
void interpolate(function* infunc)
{
infunc = new pwfunction();
cout<< (*infunc)(1.5)<<endl; //works
}
is probably not doing what you want. infunc is allocated locally, and this does not affect anything else outside or this function (and is btw a memory leak). Interpolate should either return infunc, or allocate the original variable, such as
void interpolate(function*& infunc) ...
You don't allocate array for the funclist data in somefunction, so anything can happen. Perhaps you mean
func* funclist[1];
to indicate a one-element array of func pointers.
#include <stdio.h>
#include <string.h>
void func1 (void) { printf( "1\n" ); }
void func0 (void) { printf( "0\n" ); }
typedef struct {
void (*func0)(void);
void (*func1)(void);
}mainJT;
static const mainJT coreJT = {
core_func0,
core_func1
};
mainJT currJT;
int main()
{
currJT=coreJT;
coreJT.core_func0();
getchar();
return 0;
}
Please help me fix the errors, I am sure I am making some obvious mistakes. Thanks.
Your question isn't quite clear but I see what I can find.
typedef struct {
void (*func0)(void);
void (*func1)(void);
} mainJT;
Here you are declaring a struct with function pointer members func0 and func1. Then you are trying to define a coreJT variable via an initializer list:
static const mainJT coreJT = {
core_func0,
core_func1
};
But this doesn't work, because there are no functions called core_func0 or core_func1!
Also you try to call
coreJT.core_func0();
which is also incorrect since your struct doesn't have a member of name core_func0.
For a possible solution try renaming your functions like so:
void core_func1 (void) { printf( "1\n" ); }
void core_func0 (void) { printf( "0\n" ); }
and call your function pointer by
coreJT.func0();
i see lot of errors:
for eg: the correct way of initializing a structure is :
/* Define a type point to be a struct with integer members x, y */
typedef struct {
int x;
int y;
} point;
/* Define a variable p of type point, and initialize all its members inline! */
point p = {1,2};
so your part of the code is :
mainJT coreJT = {
core_func0;
core_func1;
};
completely wrong.
also where are the functions core_func1 core_func0 are declared and defined .i cannot see them.
i guess you first need to go through structures in c
My code:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
class myClass {
public:
myClass() {
init();
}
void init() {
_myVector.push_back("Hello");
_myVector.push_back("World");
_myVector.push_back("Bye!");
for_each (_myVector.begin(), _myVector.end(), &myClass::print);
}
void print(string &myStr) {
cout << myStr << "." << endl;
}
private:
vector<string> _myVector;
};
int main() {
myClass myObj;
return 0;
}
If _myVector contained myClass objects or pointers, I could use std::mem_fun_ref or std::mem_fun. Is there any way to do the above? And yes, I do not want myClass::print to be static.
for_each (_myVector.begin(), _myVector.end(), &myClass::print);
to be replaced with
for_each (_myVector.begin(), _myVector.end(), bind1st(mem_fun(&myClass::print), this));