Link to home
Start Free TrialLog in
Avatar of mikrodidakt
mikrodidakt

asked on

STL for_each and iterator implemmentation?

Hi!

This is my first time that I am using STL and I have some question about it.
The thing that I am trying to do is to use for_each algorithm on a array of  structurs. So i have created a class that is handling this array and a iterator class to use for the for_each algorithm.

First my MessageHandler this is the class handling the structur
typedef struct{
        unsigned __int32 Param_code;
        unsigned __int32 Time;
        unsigned __int32 Measure_Value;
}S_record;
typedef struct{
        //--------HEADERS-------
        unsigned __int16 STX;
      unsigned __int16 CRC;
        unsigned __int16 MachID;
        unsigned __int16 ClinicalSWID;
        unsigned __int32 MsgCounter;
        unsigned __int32 CmdCode;
        unsigned __int32 MsgInfo;
        unsigned __int32 Flags;
        unsigned __int32 PatId;
        //----------------------
        S_record records[8];
}Message;

class MessageIterator;

class MessageHandler {
        friend class MessageIterator;
        public:
                MessageHandler(Message* mes);
                .....
                ..........
                MessageIterator begin();
                MessageIterator end();
        private:
                .....
                Message* message;
};
MessageIterator MessageHandler::begin() {
        return  MessageIterator(*this, 0);
}
MessageIterator MessageHandler::end() {
        int size = sizeof(message->records) / sizeof(S_record);
        return  MessageIterator(*this, size);
}

and then i have the iterator class
class MessageIterator {
        public:
                MessageIterator(MessageHandler& m, int p) : mh(m), pos(p) {};
                bool operator!=(const MessageIterator& messitr) const;
                MessageIterator& operator++();
                S_record operator*();
        private:
                MessageHandler mh;
                int pos;
};
bool MessageIterator::operator!=(const MessageIterator& messitr) const {
        return (pos != messitr.pos);
}
MessageIterator& MessageIterator::operator++() {
        ++pos;
        return *this;
}
S_record MessageIterator::operator*() {
        return mh.message->records[pos];
}

and then in a button even I would like to use for_each like this

std::for_each(mh.begin(), mh.end(), function to plot values);

the problem is that i dont know for sure how to use the for each. the function should plot two values from each record in the arry on a graph, something like graph1->plot_XY(each_record.x,each_record.y);

The closest i have com is following

template<class T> struct print : public std::unary_function<T, void>
{
  print(TGraph& g) : graph(g) {}
  void operator() (T x) { graph.plot_XY(x.Measure_Value, x.Time); }
  TGraph& graph;
};

void __fastcall TForm1::ConnectButtonClick(TObject *Sender)
{
    std::for_each(mh.begin(), mh.end(), print<S_record>(*graph1));
}

I appreciate all comments on this question even the small ones if i have used pointer or reference in the wrong way.

Thanks
Avatar of mikrodidakt
mikrodidakt

ASKER

The problem is that i dont get the result that i would like to get and i cant debug the template

Thanks
Hi there,

the third argument to for_each is a reference to a function to be executed for_each item

//-----------------------------------------------
std::vector <CMyItem> Items;

//* if the function you would like to execute for each item is a member function .
//* you need to generate a pointer to that member function
//* mem_fun_ref will do that for you .. it will actually create a functor I think its called.

std::for_each(Items.begin(), Items.end(), std::mem_fun_ref( &CMyItem::DoSomehing));

/* otherwise - global function*/
std::for_each(Items.begin(), Items.end(),  &DoSomehingElse));


//** defined somwhere, declared prior to for_each()
void DoSomehingElse(CMyItem &Item)
{
      ;
}

Cheers Sebastian

ASKER CERTIFIED SOLUTION
Avatar of cwwkie
cwwkie

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
and to debug a gui program, I would recommend adding OutputDebugString statements and http://www.sysinternals.com/Utilities/DebugView.html to view them.
Thanks for the answers!

I got it to work i hade just misunderstud the result on the graph.
Do u have any suggestions on when to use STL and when it is overkill.
> Do u have any suggestions on when to use STL and when it is overkill.

I would just suggest to use it when you need it!
If you create something yourself, it costs time to create it, costs time to test and debug it. With the stl you get everything ready to use. And you might be able to write for example a for_each for your situation which runs faster, but on nowadays computers it is not worth the effort. It is much more important to write maintainable and reusable code.
But by using STL and templates is't the code more reusable then if i wore going to write a for-loop that iterator through the array?

Thanks for all your answers.
Yes, if you are doing something like below, it is not very reusable, but because the STL defines standard interfaces and templates, functions can be easier used for other datatypes/other situations.

S_record *records;
int recordsize;

recordsize=10;
records=new S_record[recordsize];

...

for(int i=0; i<recordsize; ++i)
    graph.plot_XY(records[i].Measure_Value, records[i].Time);