Calling a vector of function pointer - c++

I am trying to use vector of function pointer in C++ which belongs to one class and being called in another class. For example: In class BoundaryCondition (file BoundaryCondition.h), I initialize the function pointer as:
class BoundaryConditions{
public:
// Constructor function
BoundaryConditions(int id = 0);
vector <void (BoundaryConditions::*) (Face &, int, int)> func2bcond;
void fixedValue(Face &face, int id, int rkStep);
// and other functions with similar definition as fixedValue
}
In another class (DG.h), I initialize an array of BoundaryCondition instance, something like
BoundaryCondition *bcond;
and assign memory to bcond variable using new (in file DG.cpp). For each bcond[i] instance, I need to assign memory to function pointer as:
this->bcond[i].func2bcond.resize(totNoOfVariable);
I am using resize instead of pushback as file reading may not be in the required order. Next, I am assigning function to this function pointer (again in DG.cpp) as per my boundary condition file:
bcond[i].func2bcond[j] = (&BoundaryConditions::fixedValue);
The code compiles alright till this point. I am getting error when I try to call these functions. I call this in DG.cpp. The code is as follows:
(bcond[i].*func2bond[j])(f,1,2);
I keep getting the following error:
error: 'func2bcond' was not declared in this scope
I am quite sure it is only matter of position of * or the brackets, but I am stuck here and I did not get any specific solved post on stackoverflow.
Thanks in advance

Pointer on method requires instance when called, so your code might look like:
(bcond[i].*(bcond[i].func2bond[j]))(f, 1, 2);
or, splitting expression:
auto methodPtr = bcond[i].func2bond[j]; // auto is `void (BoundaryConditions::*) (Face &, int, int)`
(bcond[i].*methodPtr)(f, 1, 2);

Related

C++ class filler syntax error

My class is as follows:
class stats {
public: int strength,
perception,endurance,charisma,inteligence,agility,luck,health,stamina,mana,karma;
};
As far as I know, there shouldn't be anything wrong with it, unless I need to set up a constructor and destructor.
I create my object using the following line:
stats* mainstat=new stats;
And I have the following function to "fill" objects of the said class:
void statfiller(stats* object, int table[]){
object->strength=table[0]; object->perception=table[1];
object->endurance=table[2]; object->charisma=table[3];
object->inteligence=table[4]; object->agility=table[5];
object->luck=table[6]; object->health=table[7];
object->stamina=table[8]; object->mana=table[9];
object->karma=table[10];
}
So, until then, no problem. At least, until the following:
I create a table with the data to fill, then feed it to my fill function.
int tablet[10]; tablet[0]=5; tablet[1]=5; tablet[2]=5; tablet[3]=5;
tablet[4]=5; tablet[5]=5; tablet[6]=5; tablet[7]=50; tablet[8]=50;
tablet[9]=50; tablet[10]=0;
statfiller(mainstat*,tablet);
When I do this, a compiling error comes up, stating the syntax of my function is incorrect.
Why is it so? Do I need to use pointer(*) or address(&)? Is there something I'm missing?
Odds are, the solution is very simple, but at the moment of typing this, I just don't see what's wrong with it ^^;
Solution to this problem was the following:
The function's syntax is "void statfiller(stats* object, int table[]) ", where the stats* object serves as reference, pointer to an object of stats class.
In the function's call "statfiller(mainstat*,tablet);", the mistake I made was calling a pointer of a stat object (in this case mainstat) instead of just putting in the object.

No Matching function to call C++

I have 2 classes TreeManager and TreeProducerBase. I am getting an error in passing an object of TTree( which is a class to make trees) to a function in TreeProducerBase from TreeManagerconstructor.
Note : I have defined tree as
TTree *tree_
Function call :
tpb.initialize(&tree_);
Here, tpb is an object of TreeproducerBase class.
This is the function that is being called.
void initialize(TTree &tree_)
It shows the error as follows:
error: no matching function for call to 'TreeProducerBase::initialize(TTree*&)'
Where am I doing wrong?
You are trying to pass pointer-to-pointer-to-TTree to a function that expects reference-to-TTree. Try redeclare it like
void initialize(TTree* &tree_);
Invokation will look like
tpb.initialize(tree_);
And then you can initialize outer pointer via simple assignment:
void initialize(TTree* &tree_) {
tree_ = new TTree(); // or smth else
}

Using functions from classes

I am learning C++ and very new at using classes, and I am getting very confused in trying to use them. I am trying to convert my existing code (which used structs) so that it uses classes - so while I know what I am trying to do I don't know if I'm doing it correctly.
I was told that when using functions from the class, I first need to instantiate an object of the class. So what I have tried (a snippet) in my main function is:
int main()// line 1
{
string message_fr_client = "test"; //line2
msgInfo message_processed; //line 3
message_processed.incMsgClass(message_fr_client); //line 4
if (!message_processed.priority_check(qos_levels, message_processed)) //line 5
cout << "failure: priority level out of bounds\n"; //line 6
return 0; //line 7
}
Could you help me clarify if my following assumptions are correct? The compiler is not showing any error and so I don't know if it is error-free, or if there are ones lurking beneath.
At line 4, is the function incMsgClass being performed on the string message_fr_client and returning the resultant (and modified) message_processed?
At line 5, the function priority_check is being performed on the message_processed and returning a boolean?
In my class definition, I have a function getPath that is meant to modify the value of nodePath - is it just a matter of using message_processed.getPath(/*arguments*/)?
I haven't included the body of the functions because I know they work - I would just like to find out how the class functions interact. Please let me know if I can be clearer - just trying to clear up some confusion here.
Here is my class:
#ifndef clientMsgHandling_H
#define clientMsgHandling_H
#include <list>
#include <map>
#include <queue>
class msgInfo
{
public:
msgInfo();
msgInfo(int, int, int, std::string, std::list<int>);
/*classifying message*/
msgInfo incMsgClass(std::string original_msg);
/*message error checks*/
bool priority_check(int syst_priority, msgInfo msg); //check that message is within qos levels
bool route_check(std::map<std::pair<int, int>, int> route_table, msgInfo msg); //check that route exists
void getPath(msgInfo msg, std::map<std::pair<int, int>, int> route_info, int max_hop);
private:
int source_id;
int dest_id;
int priority;
std::string payload;
std::list<int> nodePath;
};
#endif
While it may compile (and even run), there are a few oddities with the code as shown:-
First off, class methods know which object they are operating on - so your priority_check and route_check methods probably don't need msgInfo as a parameter.,
for example, your old non-class function might be like this
bool priority_check(int p, msgInfo msg)
{
return msg.priority < p;
}
But the new one should look like this:
bool msgInfo::priority_check(int p)
{
return priority < p;
}
Also, incMsgClass is a bit odd, as it's a non-static class method that returns a msgInfo object. It's difficult to tell without understanding what it's supposed to do, but it seems possible that this function should actually be a constructor, rather than a regular method.
One other thing is that you're currently passing a msgInfo by value to those methods. So if the method needed to modify the passed msgInfo, it would not have any effect. It's generally better to pass objects by reference or const reference to other methods. So, back to the previous non-method example, it should really be this.
bool priority_check(int p, const msgInfo &msg)
...
But, as I said, you probably don't need the msgInfo parameters anyway.
At line 4, is the function incMsgClass being performed on the string message_fr_client
Yes
and returning the resultant (and modified) message_processed?
Whatever it's returning, you're ignoring the return value. It can modify the object itself, yes, because the function is not const.
At line 5, the function priority_check is being performed on the message_processed and returning a boolean?
Yes
In my class definition, I have a function getPath that is meant to modify the value of nodePath - is it just a matter of using message_processed.getPath(/arguments/)?
If a member function is intended to modify one of the class members, it's just a matter of not marking that function const
Hard to tell without implementation-details, but here we go:
I. You are passing a std::string as value (C++ is call-by-value by default), so you get a copy of the std::string in your method. If you want to work on the object you passed and manipulate it, use a reference on the object, like
msgInfo incMsgClass(std::string& original_msg); // notice the ampersand
then you can change your signature to
void incMsgClass(std::string& original_msg);
as you don't need to return the std::string you passed.
II. Yes, at least according to your signature
III. Can see a node_path only as a member.
For all your questions, see C++-FAQ.
Your basic assumptions are correct.
message_processed.incMsgClass(message_fr_client); //line 4
This line is not correct. The function you call returns msgInfo which is simply dropped. You should assign it to something. But it is not as it is usually done. You should make it a constructor of msgInfo, like
class msgInfo
{
public:
msgInfo(std::string original_msg);
...
}
Then you could call it like this
msgInfo message_processed(message_fr_client);
That line would create a msgInfo that is already properly initialized.
There is another pattern for creating class instances - static creating function. In your case you could mark incMsgClass static and then call it like
msgInfo message_processed = msgInfo.incMsgClass(message_fr_client);
I seriously doubt you need this pattern here, so I'd advise to move to constructor.
As of other functions, I see no problems there. Just note that all member functions not marked as const can modify the object they are called on. So, you don't need to pass this object explicitly. For functions a pointer to the object they are called on is available by name this. Also the functions can access all class variables as if these variables are global for normal (non-member) functions.

C++ - Smart Pointers - Passing derived class shared pointer to base through template

I have the following and having difficulty resolving the error please help.
i have the following class as template definition somewhere.
template<class ConcreteHandlerType>
class SomeAcceptor: public ACE_Acceptor<ConcreteHandlerType, ACE_SOCK_Acceptor>
In some other file, i initialize this class in the constructor
class initialize {
typedef SomeAcceptor<BaseClassSomeHandler> baseAcceptor_t;
typedef SomeAcceptor<DerivedClassSomeHandler> derivedAcceptor_t;
boost::shared_ptr<baseAcceptor_t;> mAcceptor;
boost::shared_ptr<derivedAcceptor_t;> mDerivedAcceptor;
bool HandleAcceptNotification(BaseClassSomeHandler& someHandler);
initialize() : mAcceptor(0), mDerivedAcceptor(new DerivedAcceptor_t) {
mAcceptor->SetAcceptNotificationDelegate(fastdelegate::MakeDelegate(this, &initialize::HandleAcceptNotification));
}
}
Error i get is
error: no matching function for call to `boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >::shared_ptr(int)'common/lib/boost_1_39_0/boost/smart_ptr/shared_ptr.hpp:160: note: candidates are: boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >::shared_ptr(const boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >&)
common/lib/boost_1_39_0/boost/smart_ptr/shared_ptr.hpp:173: notboost::shared_ptr<T>::shared_ptr() [with T = SomeAcceptor<BaseClassSomeHandler>]
I also tried overloading the function with
bool HandleAcceptNotification(DerivedClassSomeHandler& someHandler);
but because mAcceptor is of type SomeAcceptor BaseClassSomeHandler, i get this error, but to fix this.
I guess i need to cast it somehow, but how to do it?
i tried doing like below inside the constructor and it didn't work
initialize() : mAcceptor(0), mDerivedAcceptor(new DerivedAcceptor_t) {
mAcceptor = mDerivedAcceptor; // Error here
mAcceptor->SetAcceptNotificationDelegate(fastdelegate::MakeDelegate(this, &initialize::HandleAcceptNotification));
}
From your code, it looks like you want mAcceptor to be assigned NULL (0), if that is the case you don't need to initialize it at all, as the default constructor will take care of that. But, since you call a function on that (NULL) pointer immediately, its not immediately clear exactly what you want to do.
If you want mAcceptor and mDerivedAcceptor to point to the same (shared) object and assuming DerivedClassSomeHandler is derived from BaseClassSomeHandler, this is a situation where you should use boost::shared_static_cast, as described here.
There's also some good information in this apparently related question.
The error is due to the mAcceptor(0) in
initialize() : mAcceptor(0), mDerivedAcceptor(new DerivedAcceptor_t) {
mAcceptor->SetAcceptNotificationDelegate(fastdelegate::MakeDelegate(this, &initialize::HandleAcceptNotification));
}
The smart_ptr default constructor assigns the wrapped ptr to NULL, so leave out mAcceptor(0) from the initialization list.
boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >::shared_ptr(int)
It's yelling at you that there's no constructor that accepts an int.
Just use: mAcceptor()

C++ boost function issue

I did something to break the functionality in my program, but I can't figure out what. I define a typedef in a class headerfile:
typedef boost::function<void(instr_ptr, std::vector<ResultBase*>) > GenFunction;
And inside that class I have two instances:
GenFunction Gen;
GenFunction Kill
I set them as follows:
void DataFlowSolver::SetGenFunction(GenFunction &func)
{
Gen = func;
}
void DataFlowSolver::SetKillFunction(GenFunction &func)
{
Kill = func;
}
I have another function in a seperate header file:
void GenLiveVar(const instr_ptr instr, std::vector<ResultBase*> &list);
I create an instance of the DataFlowSolver class, and attempt to assign into it as follows:
blockSolver.SetGenFunction(GenLiveVar);
However, the compiler complains:
CFG.cc:617: error: no matching function for call to
'DataFlowSolver::SetGenFunction(void (&)(instr_ptr,
std::vector >&))'
DataFlowSolver.h:21: note: candidates are: void
DataFlowSolver::SetGenFunction(GenFunction&)
But it lets me do this:
GenFunction fun = GenLiveVar;
blockSolver.SetGenFunction(fun);
Anyone have an idea what might be wrong? I know this worked before, but I'm not sure how I managed to break it...
You are passing the boost::function into Set*Function by non-const reference. That prevents temporaries from being used as arguments, and the conversion from a normal function to a boost::function creates a temporary value. You will need to use a const reference for your parameter type for the code to work correctly.