i try store a functions(methods) from class in array and use them.
The error handle is
In function 'int main()':| 'actions' was not declared in this
scope
this my code(i delete unnecessary code)
the class.h:
class Calculator
{
public:
int num1,num2;
void (Calculator::*actions[4])();
void add();
void minuz();
void multi();
void div();
Calculator();
};
class.cpp:
void Calculator::add()
{}
void Calculator::minuz()
{}
void Calculator::div()
{ }
void Calculator::multi()
{}
Calculator::Calculator()
{
actions[0]=add;
actions[1]=minuz;
actions[2]=div;
actions[3]=multi;
}
main:
Calculator cal;
.....
.....
cal.*actions[num]();
C++ syntax for function pointer declaration is quite complicated, so it better use typedefs
To call function by pointer you need extra () around dereferenced function pointer.
Finally it will be:
class Calculator
{
public:
typedef void (Calculator::*action)();
int num1,num2;
action actions[4];
void add();
void minuz();
void multi();
void div();
Calculator();
};
void Calculator::add()
{}
void Calculator::minuz()
{}
void Calculator::div()
{ }
void Calculator::multi()
{}
Calculator::Calculator()
{
actions[0]=&Calculator::add;
actions[1]=&Calculator::minuz;
actions[2]=&Calculator::div;
actions[3]=&Calculator::multi;
}
int main(int, char**) {
Calculator cal;
int num = 0;
(cal.*cal.actions[num])();
return 0;
}
for better readability I'd suggest add function Calculator::call_by_index(int):
void Calculator::call_by_index(int index)
{
(this->*actions[index])();
}
and call it in such way:
cal.call_by_index(num);
Using a typedef usually helps: (c++03)
Live On Coliru
class Calculator
{
public:
int num1,num2;
typedef void (Calculator::*Action)();
Action actions[4];
Calculator() {
actions[0]=&Calculator::add;
actions[1]=&Calculator::minuz;
actions[2]=&Calculator::div;
actions[3]=&Calculator::multi;
}
private:
void add() {}
void minuz() {}
void multi() {}
void div() {}
};
int main() {
Calculator cal;
(cal.*cal.actions[1])();
}
C++11 aliases
C++11 makes it easier:
using Action = void (Calculator::*)();
Action actions[4];
See also https://isocpp.org/wiki/faq/pointers-to-members#fnptr-vs-memfnptr-types
Live On Coliru
std::function<>
Also in c++11 (or boost if you want it in c++03):
using Action = std::function<void(Calculator&)>;
Action actions[4];
Which you would still call like
cal.actions[1](cal);
I'd pre-bind to the Calculator instance:
Live On Coliru
#include <functional>
class Calculator
{
public:
int num1,num2;
using Action = std::function<void()>;
Action actions[4];
Calculator() {
actions[0] = [this]() { add(); };
actions[1] = [this]() { minuz(); };
actions[2] = [this]() { multi(); };
actions[3] = [this]() { div(); };
}
private:
void add() {}
void minuz() {}
void multi() {}
void div() {}
};
int main() {
Calculator cal;
cal.actions[1]();
}
You're not calling it right. Since actions is a member of Calculator, you need to reference a Calculator object to get at it.
(cal.*(cal.actions[num]))();
The first cal is the object you're wanting to call the action with, and the second cal is used to access the action you want to call.
Related
So my problem starts pretty much like this question:
Start thread with member function
I have some class Foo, that looks like this:
struct Foo
{
int y;
thread t;
void set(int x){
y = x;
}
void plan(int x){
thread = std::thread ([&]{
set(x);
});
void get(){
if (t.joinable())
t.join();
}
};
Other answers also suggest:
void plan(int x){
thread = std::thread(&Foo::set, this, x);
};
Now, I want to use Foo as a base class for various child class with overloaded set() functions, for exemple:
struct Bar: public Foo
{
void set(int x){
y = x*2;
}
}
My problem is that if done that way, Bar::plan() result in Foo::set() being runned in the new thread instead of Bar::set as expected.
Is there another solution than having to write again the plan() method in every child class of Foo?
You might simply make set virtual:
struct Foo
{
// ...
virtual void set(int x);
};
struct Bar : Foo
{
void set(int x) override;
};
Just mark set as virtual and use the lambda version, being careful to capture everything by value, as the plan invocation may (and probably will) return before the thread actually start to run.
struct Foo
{
int y;
thread t;
virtual void set(int x){
y = x;
}
void plan(int x){
t = std::thread ([this, x]{
this->set(x);
});
}
void get(){
if (t.joinable())
t.join();
}
};
this will call the correct set version even when plan is invoked in a derived class.
Though the answer has been accepted already, Here is a way to do the same using std::bind.
#include <iostream>
#include <thread>
#include <functional>
using namespace std;
struct Foo
{
int y;
thread t;
virtual void set(int x){
y = x;
}
void plan(int x){
t = std::thread (std::bind(&Foo::set, this, x));
}
void get(){
if (t.joinable())
t.join();
}
};
struct Bar: public Foo
{
void set(int x){
cout << "Called" << endl;
y = x*2;
}
};
int main() {
Bar b;
b.plan(2);
b.get();
return 0;
}
Also, Without using lambda, you could have done this also:
void plan(int x){
t = std::thread (&Foo::set, this, x);
}
I have some problem compiling my code.
I have the following structure:
#include <cstdlib>
using namespace std;
typedef double (*FuncType)(int );
class AnotherClass {
public:
AnotherClass() {};
double funcAnother(int i) {return i*1.0;}
};
class MyClass {
public:
MyClass(AnotherClass & obj) { obj_ = &obj;};
void compute(FuncType foo);
void run();
protected:
AnotherClass * obj_; /*pointer to obj. of another class */
};
void MyClass::compute(FuncType foo)
{
int a=1;
double b;
b= foo(a);
}
void MyClass::run()
{
compute(obj_->funcAnother);
}
/*
*
*/
int main(int argc, char** argv) {
AnotherClass a;
MyClass b(a);
b.run();
return 0;
}
When I try to compile it, it gives:
main.cpp:39:31: error: no matching function for call to ‘MyClass::compute(<unresolved overloaded function type>)’
main.cpp:30:6: note: candidate is: void MyClass::compute(double (*)(int))
What's wrong here?
p/s/ AnotherClass * obj_; should stay like that because I write some function to the big library and can't change it.
-------------- working version by Benjamin -------
#include <cstdlib>
using namespace std;
class AnotherClass {
public:
AnotherClass() {};
double funcAnother(int i) {return i*1.0;}
};
struct Foo
{
/*constructor*/
Foo(AnotherClass & a) : a_(a) {};
double operator()(int i) const
{
return a_.funcAnother(i);
}
AnotherClass & a_;
};
class MyClass {
public:
MyClass(AnotherClass & obj) { obj_ = &obj;};
template<typename FuncType>
void compute(FuncType foo);
void run();
protected:
AnotherClass * obj_; /*pointer to obj. of another class */
};
template<typename FuncType>
void MyClass::compute(FuncType foo)
{
int a=1;
double b;
b= foo(a);
}
void MyClass::run()
{
Foo f(*obj_);
compute(f);
}
/*
*
*/
int main(int argc, char** argv) {
AnotherClass a;
MyClass b(a);
b.run();
return 0;
}
Thank you everybody very much for the help!
Since,
funcAnother(int i);
is a member function it passes an implicit this and then the prototype does not match the type of your function pointer.
The typedef for pointer to member function should be:
typedef double (AnotherClass::*funcPtr)(int);
Here is a modified compilable version of your code. Please check the comments inline to understand the changes, Also I left out the other details, you can add that up.
The following function class will match the signature of your FuncType:
struct Foo
{
AnotherClass & a_;
Foo(AnotherClass & a) a_(a) {}
double operator()(int i) const
{
return a_.funcAnother(i);
}
};
Change MyClass::compute to a template, thusly:
template<typename FuncType>
void MyClass::compute(FuncType foo)
{
int a=1;
foo(a);
}
Then you can call run like this:
void MyClass::run()
{
compute(Foo(*obj_));
}
If your compiler supports lambdas (and there's a good chance it does), then you can forgo the function class and simply define run like this:
void MyClass::run()
{
auto f = [this](int i) {
return obj_->funcAnother(i);
};
compute(f);
}
I've never used function pointers before and I'm having some trouble getting my code to work. This is what I have
TestClass.h:
class TestClass
{
public:
void function1();
void function2();
void function3(void (*funcPtr)(void))
void function4();
};
TestClass.cpp
void TestClass::function1()
{
//CODE
}
void TestClass::function2()
{
//CODE
}
void TestClass::function3(void (*funcPtr)(void))
{
//CODE
funcPtr();
//CODE
}
void TestClass::function4()
{
function3(function1);
function3(function2);
}
This give me the error
"nonstandard form for taking the address of a member function
I tried to add TestClass:: infront of the *funcPtr but that gives me even more errors
With member function pointer, it should be something like:
void TestClass::function3(void (TestClass::*funcPtr)())
{
//CODE
(this->*funcPtr)();
//CODE
}
void TestClass::function4();
{
function3(&TestClass::function1);
function3(&TestClass::function2);
}
With function pointer
class TestClass
{
public:
static void function1(); // static added
static void function2(); // static added
void function3(void (*funcPtr)(void))
void function4();
};
void TestClass::function3(void (*funcPtr)())
{
//CODE
funcPtr();
//CODE
}
void TestClass::function4();
{
function3(&TestClass::function1);
function3(&TestClass::function2);
}
I suggest you to use std::bind and std::function, which provide a better readability and more checking for you
http://en.cppreference.com/w/cpp/utility/functional/bind
#include <functional>
void TestClass::function3( std::function<void (void)> funcPtr )
{
//CODE
funcPtr();
//CODE
}
void TestClass::function4()
{
function3( std::bind(&TestClass::function1, this) );
function3( std::bind(&TestClass::function2, this) );
}
This list, has to hold functions, they might be from different namespaces and even methods of instanced classes.
This list will then be iterated and all the functions and methods called. It would be nice if they could contain arguments also.
I was thinking on using a std::vector, but I suspect that I am far from correct in that guess.
What approach do you recommend me? All help is welcome.
You could use std::function and std::bind if your compiler already supports it.
#include <functional>
#include <vector>
void x(int) {}
void y() {}
class Z {
public:
void z() {}
};
int main(int argc, char *argv[])
{
typedef std::function<void ()> VoidFunc;
typedef std::vector<VoidFunc> FuncVector;
FuncVector functions;
functions.push_back(std::bind(&x, 1));
functions.push_back(&y);
Z z1;
functions.push_back(std::bind(&Z::z, z1));
for(FuncVector::iterator i = functions.begin(); i != functions.end(); i++) {
(*i)();
}
return 0;
}
Have all of your functions implement the Command Pattern.
Your list becomes a
std::list<Command>
As you iterate over the list, you invoke the Execute() method of each list item.
For example, say you have a simple Command interface called Commander:
class Commander
{
public:
virtual ~Commander;
virtual void Execute();//= 0;
};
And you have three objects that you want to put in your list: A Greyhound, a Gyrefalcon, and a Girlfriend. Wrap each in a Commander object that calls the object's function of interest. The Greyhound runs:
class RunGreyhound: public Commander
{
public:
void Execute()
{
mGreyhound->Run();
}
private:
Greyhound* mGreyhound;
};
The Gyrefalcon flies:
class RunGyrefalcon: public Commander
{
public:
void Execute()
{
mGyrefalcon->Fly( mGyrefalcon->Prey() );
}
private:
Gyrefalcon* mGyrefalcon;
};
And the Girlfriend squawks:
class RunGirlfriend: public Commander
{
public:
void Execute()
{
mGirlfriend->Squawk( mGirlfriend->MyJunk(), mGirlfriend->Mytrun() );
}
private:
Girlfriend* mGirlfriend;
};
Stuff the Commander objects in your list. Now you can iterate over them and invoke each element's Execute() method:
std::list<Commander> cmdlist;
RunGreyhound dog;
cmdlist.push_back( dog );
RunGyrefalcon bird;
cmdlist.push_back( bird );
RunGirlfriend gurl;
cmdlist.push_back( gurl );
for ( std::list<Commander>::iterator rit = cmdlist.begin(); rit != cmdlist.end(); ++rit )
{
rit->Execute();
}
If you don't want to use an existing solution such as boost::function, you will need to create a base class that represents a function, and then derived classes that wrap various sources of functions. For example:
#include <iostream>
#include <list>
using std::cout;
using std::list;
struct Function {
virtual ~Function() { }
virtual void operator()() = 0;
};
struct PlainFunction : Function {
PlainFunction(void (*function_ptr_arg)()) : function_ptr(function_ptr_arg) { }
virtual void operator()() { (*function_ptr)(); }
void (*function_ptr)();
};
template <typename T>
struct MethodFunction : Function {
MethodFunction(T &obj_arg,void (T::*method_ptr_arg)())
: obj(obj_arg), method_ptr(method_ptr_arg)
{
}
virtual void operator()() { (obj.*method_ptr)(); }
T &obj;
void (T::*method_ptr)();
};
void f()
{
cout << "Called f()\n";
}
struct A {
void f() { cout << "Called A::f()\n"; }
};
int main(int argc,char **argv)
{
list<Function *> functions;
functions.push_back(new PlainFunction(f));
A a;
functions.push_back(new MethodFunction<A>(a,&A::f));
list<Function *>::iterator i = functions.begin();
for (;i!=functions.end();++i) {
(*(*i))();
}
while (!functions.empty()) {
Function *last_ptr = functions.back();
functions.pop_back();
delete last_ptr;
}
}
I have some problem compiling my code.
I have the following structure:
#include <cstdlib>
using namespace std;
typedef double (*FuncType)(int );
class AnotherClass {
public:
AnotherClass() {};
double funcAnother(int i) {return i*1.0;}
};
class MyClass {
public:
MyClass(AnotherClass & obj) { obj_ = &obj;};
void compute(FuncType foo);
void run();
protected:
AnotherClass * obj_; /*pointer to obj. of another class */
};
void MyClass::compute(FuncType foo)
{
int a=1;
double b;
b= foo(a);
}
void MyClass::run()
{
compute(obj_->funcAnother);
}
/*
*
*/
int main(int argc, char** argv) {
AnotherClass a;
MyClass b(a);
b.run();
return 0;
}
When I try to compile it, it gives:
main.cpp:39:31: error: no matching function for call to ‘MyClass::compute(<unresolved overloaded function type>)’
main.cpp:30:6: note: candidate is: void MyClass::compute(double (*)(int))
What's wrong here?
p/s/ AnotherClass * obj_; should stay like that because I write some function to the big library and can't change it.
-------------- working version by Benjamin -------
#include <cstdlib>
using namespace std;
class AnotherClass {
public:
AnotherClass() {};
double funcAnother(int i) {return i*1.0;}
};
struct Foo
{
/*constructor*/
Foo(AnotherClass & a) : a_(a) {};
double operator()(int i) const
{
return a_.funcAnother(i);
}
AnotherClass & a_;
};
class MyClass {
public:
MyClass(AnotherClass & obj) { obj_ = &obj;};
template<typename FuncType>
void compute(FuncType foo);
void run();
protected:
AnotherClass * obj_; /*pointer to obj. of another class */
};
template<typename FuncType>
void MyClass::compute(FuncType foo)
{
int a=1;
double b;
b= foo(a);
}
void MyClass::run()
{
Foo f(*obj_);
compute(f);
}
/*
*
*/
int main(int argc, char** argv) {
AnotherClass a;
MyClass b(a);
b.run();
return 0;
}
Thank you everybody very much for the help!
Since,
funcAnother(int i);
is a member function it passes an implicit this and then the prototype does not match the type of your function pointer.
The typedef for pointer to member function should be:
typedef double (AnotherClass::*funcPtr)(int);
Here is a modified compilable version of your code. Please check the comments inline to understand the changes, Also I left out the other details, you can add that up.
The following function class will match the signature of your FuncType:
struct Foo
{
AnotherClass & a_;
Foo(AnotherClass & a) a_(a) {}
double operator()(int i) const
{
return a_.funcAnother(i);
}
};
Change MyClass::compute to a template, thusly:
template<typename FuncType>
void MyClass::compute(FuncType foo)
{
int a=1;
foo(a);
}
Then you can call run like this:
void MyClass::run()
{
compute(Foo(*obj_));
}
If your compiler supports lambdas (and there's a good chance it does), then you can forgo the function class and simply define run like this:
void MyClass::run()
{
auto f = [this](int i) {
return obj_->funcAnother(i);
};
compute(f);
}