Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Member function pointer in C++ for_each

I'm developing a small Virtual Machine in C++ for a school project, which should work like dc command, and is composed of a Input Output element, a Chipset, a Cpu and Ram. I'm currently working on the chipset, in which I've implemented a little parsing class in order to be able to get some Asm instructions from standard input or file, and then push this instructions to the Cpu.

The problem is: my instructions are sorted in a std::list, and I'd like to be able to push them each by each with a foreach instruction. To do that I need to be able to call my member function "push_instruction" as the function pointer F of for_each; and I wasn't able to find the trick to do that...

Any ideas? here's my code:

/*
** Function which will supervise
** the lexing and parsing of the input (whether it's std_input or a file descriptor)
** the memory pushing of operands and operators
** and will command the execution of instructions to the Cpu
*/
void                    Chipset::startExecution()
{
    /*
    ** My parsing 
    ** Instructions
    **
    */

    for_each(this->_instructList.begin(), this->_instructList.end(), this->pushInstruction);
}


void                    Chipset::pushInstruction(instructionList* instruction)
{
    if (instruction->opCode == PUSH)
      this->_processor->pushOperand(instruction->value, Memory::OPERAND, Memory::BACK);
    else if (instruction->opCode == ASSERT)
      this->_processor->pushOperand(instruction->value, Memory::ASSERT, Memory::BACK);
    else
      this->_processor->pushOperation(instruction->opCode);
}
like image 802
Oleiade Avatar asked Feb 19 '11 11:02

Oleiade


3 Answers

std::for_each(
    _instructList.begin(), 
    _instructList.end(), 
    std::bind1st(std::mem_fun(&Chipset::pushInstruction), this));
like image 130
Erik Avatar answered Nov 10 '22 22:11

Erik


When you can't remember the syntax for the std::bind functions, it is sometimes easier to write a functor which just forwards to the member function:

struct PushInstruction {
  PushInstruction(Chipset& self) : self(self) {} 

  void operator()(instructionList* instruction) {
    self.pushInstruction(instruction);
  }    

  Chipset& self;    
};

std::for_each(_instructList.begin(), _instructList.end(), PushInstruction(*this));

A bit of explanation:

I define a class which, in its constructor, takes the object we want to call pushInstruction on, and which stores a reference to the object.

Then I define an operator() hich takes the instruction you wish to push, and calls pushInstruction.

In the for_each loop, I just pass this to my constructor, creating an instance of the functor, which is passed to for_each, which then calls operator() on it for each element.

like image 33
jalf Avatar answered Nov 10 '22 20:11

jalf


Use boost::bind as,

std::for_each(/*..*/, /*..*/,
            boost::bind(&Chipset::pushInstruction, this, _1));
like image 2
Nawaz Avatar answered Nov 10 '22 22:11

Nawaz