for_each on class member

Started by
9 comments, last by Sneftel 14 years, 5 months ago
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?
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.cppptest.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_FOREACHforeach(shared_ptr<GUIPanel> p, m_Panels) {    Renderer::drawGUIElement(p.get());}

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.)
#include <boost/bind.hpp>std::vector<boost::shared_ptr<GUIPanel>> m_Panels;Renderer r;//somewhere elsefor_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.
this is the render function

void D3D9Renderer::drawGUIElement(boost::shared_ptr<GUIElement> element)
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).
f@dzhttp://festini.device-zero.de
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)
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;
Yeah, I know though I never had any problem with it in visual c++ 2008.
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.

This topic is closed to new replies.

Advertisement