Jump to content
  • Advertisement
Sign in to follow this  
Black Knight

for_each on class member

This topic is 3141 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I have a vector which holds shared_ptrs the objects are derived from a base GUIElement class,I tried to use for_each to call a render method of the renderer on the objects but Im getting a compile error.Here is the code
std::vector<boost::shared_ptr<GUIPanel>> m_Panels;

//somewhere else
for_each(m_Panels.begin(),m_Panels.end(),Renderer::drawGUIElement);


Renderer::drawGUIElement takes a parameter as GUIElement is that the problem?

Share this post


Link to post
Share on other sites
Advertisement
This:
#include <memory>
using namespace std;

void foo(auto_ptr<int> p)
{
}

int main()
{
int *x = new int(42);
foo(x);
return 0;
}


Dies like:
$ g++ ptest.cpp
ptest.cpp: In function ‘int main()’:
ptest.cpp:11: error: conversion from ‘int*’ to non-scalar type ‘std::auto_ptr<int>’ requested


So...yes. Smart pointers and raw pointers are not interchangeable.

You're already using Boost, so try something like:
#define foreach BOOST_FOREACH

foreach(shared_ptr<GUIPanel> p, m_Panels) {
Renderer::drawGUIElement(p.get());
}

Share this post


Link to post
Share on other sites
Quote:
Renderer::drawGUIElement takes a parameter as GUIElement is that the problem?
Is the 'GUIElement' argument passed by value, reference, or pointer? (Maybe you could just post the function declaration for Renderer::drawGUIElement.)

Share this post


Link to post
Share on other sites

#include <boost/bind.hpp>

std::vector<boost::shared_ptr<GUIPanel>> m_Panels;
Renderer r;

//somewhere else
for_each(m_Panels.begin(),m_Panels.end(),boost::bind(&Renderer::drawGUIElement, &r, _1));




There's a way to do it with just the standard library, but I honestly haven't bothered to learn how since I discovered Boost.Bind.

Edit: I'm assuming that Renderer::drawGUIElement isn't a static function. If it is, remove the '&r' argument.

Share this post


Link to post
Share on other sites
Your way would probably work, if drawGUIElement was a static member function.

Since you're already using boost, I'd stick with bind. An alternative that isn't quite as elegant might be:


struct functor
{
functor(const Renderer& renderer)
: renderer_(renderer) {}

const Renderer& renderer_;
void operator()(const shared_ptr<GUIThingy>& element)
{
renderer.drawGUIElement(element);
}
};

for_each(begin, end, functor(my_Renderer));



Of course, once you think about there being a pattern and making a generic template solution, a simple form of bind is probably what you come up with (with bind returning a temporary functor that does the above).

Share this post


Link to post
Share on other sites
Have you tried scjohnno's code? It looks like it's probably what you're looking for.

Also, I'd probably pass the shared pointer argument by constant reference rather than by value, i.e.:
void D3D9Renderer::drawGUIElement(const boost::shared_ptr<GUIElement>& element)

Share this post


Link to post
Share on other sites
Quote:
Original post by Black Knight
std::vector<boost::shared_ptr<GUIPanel>> m_Panels;


Small nitpick: In current C++, ">>" is not allowed to close multiple template argument lists. C++0x will solve this, but is not the standard, yet, so this is the correct one:

std::vector<boost::shared_ptr<GUIPanel> > m_Panels;

Share this post


Link to post
Share on other sites
boost::shared_ptr<GUIElement> is not the same type as boost::shared_ptr<GUIPanel>, nor is it considerd a related type iirc and as I recall shared_ptr doesn't support automatic conversion between types of T directly, however you might want to check the docs on this because if I'm recalling it correctly its pretty clear about it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!