Solved

using for_each to to push items onto a queue

Posted on 2004-09-01
9
760 Views
Last Modified: 2011-10-03
i want to turn this

for( u = 0; u < graph.size(); ++u )
            Q.push( &graph[u] );

into 1 line using for_each

for_each( graph.begin(), graph.end(), bind1st( mem_fun( &priority_queue<VERTEX*, vector<VERTEX*>, VERTEX >::push ), &Q ) );

soemthing like that is the idea but i cant get it to work. how do i fix it?
0
Comment
Question by:Kitty__Kong
  • 4
  • 2
  • 2
  • +1
9 Comments
 
LVL 3

Expert Comment

by:Indrawati
ID: 11950340
OK, not sure if this is your problem here, but I always have problem using mem_fun on a member function that takes argument(s) on VC++6 (compiler error) . It seems ok though on member function that does not expect any argument.
0
 
LVL 4

Expert Comment

by:anthony_w
ID: 11951459
Download the boost libraries from www.boost.org

Now you can write:

    std::for_each(graph.begin(),graph.end(),
                  boost::lambda::bind(&priority_queue<VERTEX*, vector<VERTEX*>, VERTEX >::push,&Q,&boost::lambda::_1));

after adding

#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>

to your list of includes
0
 
LVL 1

Author Comment

by:Kitty__Kong
ID: 11954457
im using vsnet2k3

i want to to do it without boost
0
 
LVL 1

Author Comment

by:Kitty__Kong
ID: 11954478
i forgot to say graph is a vector<VERTEX>

#include <functional>
#include <algorithm>
#include <queue>
#include <vector>
 
using namespace std;
 
int main()
{
   priority_queue<int> q;
   vector<int> g;
 
   for_each(g.begin(), g.end(),
       bind1st(mem_fun(&priority_queue<int>::push), &q));
 
    return 0;
}

there is a simple example of wht i want to work
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 15

Expert Comment

by:efn
ID: 11959955
It's certainly possible to construct something that you can pass to for_each and accomplish the desired goal, but I don't think you can do it in one line.  It would have to be a function object that knows about the queue.  You can write a class for such objects, but I don't think you can whip it up out of standard library functions as you are trying to do.

But you never know, some other expert may yet enlighten us all.

--efn
0
 
LVL 4

Accepted Solution

by:
anthony_w earned 250 total points
ID: 11961684
Can I ask why you wan't to accomplish this without boost? It's free, and works well with VS.NET2003

As efn says, you can't do this with the standard library, because mem_fun doesn't work well with functions taking a reference. You could use a library that handled things properly (like boost), or you can write your own.

If you want a function object to use with for_each, use something like:

#include <functional>
#include <algorithm>
#include <queue>
#include <vector>
 
using namespace std;

template<typename T>
struct PushOnPriorityQueue
{
    priority_queue<T>& queue;

    PushOnPriorityQueue(priority_queue<T>& queue_):
        queue(queue_)
    {}
   
    void operator()(T const& valueToPush)
    {
        queue.push(valueToPush);
    }
};

template<typename T>
PushOnPriorityQueue<T> pushOnPriorityQueue(priority_queue<T>& queue)
{
    return PushOnPriorityQueue<T>(queue);
}
 
int main()
{
   priority_queue<int> q;
   vector<int> g;
 
   for_each(g.begin(), g.end(),pushOnPriorityQueue(q));
 
   return 0;
}


An alternative is to provide an output iterator that does a push, and use std::copy:

#include <functional>
#include <algorithm>
#include <queue>
#include <vector>
 
using namespace std;

template<typename T>
struct PriorityQueuePusher
{
    priority_queue<T>& queue;

    PriorityQueuePusher(priority_queue<T>& queue_):
        queue(queue_)
    {}
   
    PriorityQueuePusher& operator*()
    {
        return *this;
    }
   
    void operator=(T const& valueToPush)
    {
        queue.push(valueToPush);
    }
    void operator++()
    {}
};

template<typename T>
PriorityQueuePusher<T> makePriorityQueuePusher(priority_queue<T>& queue)
{
    return PriorityQueuePusher<T>(queue);
}
 
int main()
{
   priority_queue<int> q;
   vector<int> g;
 
   copy(g.begin(), g.end(),makePriorityQueuePusher(q));
 
    return 0;
}

0
 
LVL 1

Author Comment

by:Kitty__Kong
ID: 11965875
so what i want is impossible using just the stl? it cant be made to work using functional?
0
 
LVL 15

Expert Comment

by:efn
ID: 11966491
> so what i want is impossible using just the stl? it cant be made to work using functional?

That's my opinion.  I just hesitate to be too dogmatic, because the library is so big and obscure.

By the way, to call a member function of an object passed by reference, you can use mem_fun_ref.  But that doesn't help with this problem.

In addition to the solutions anthony_w showed, it would be possible to craft one using bind1st or bind2nd.  But like those, it would require several lines.

--efn
0
 
LVL 1

Author Comment

by:Kitty__Kong
ID: 11966797
im going to leave the question up a bit longer to see if someone comes up with a way to do what i want. if no one does i will accept one of the already posted responses.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now