• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 776
  • Last Modified:

using for_each to to push items onto a queue

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
Kitty__Kong
Asked:
Kitty__Kong
  • 4
  • 2
  • 2
  • +1
1 Solution
 
IndrawatiCommented:
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
 
anthony_wCommented:
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
 
Kitty__KongAuthor Commented:
im using vsnet2k3

i want to to do it without boost
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
Kitty__KongAuthor Commented:
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
 
efnCommented:
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
 
anthony_wCommented:
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
 
Kitty__KongAuthor Commented:
so what i want is impossible using just the stl? it cant be made to work using functional?
0
 
efnCommented:
> 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
 
Kitty__KongAuthor Commented:
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

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

  • 4
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now