0

I really need help for a excercise in C++ at the University. I have no idea how to solve it. There is one Class with this memberfunction: void Asteroid::render() which is also virtual and I have to call this function from another class in the following way.

I have a template list which contains many asteroids, this is the class with the member function and the template has a function to pass over the function which should be called. void for_each(void (*do_something)(T item)); here I have to pass the pointer to void Asteroid::render() T in template are objects of the class Asteroid. So the final call in a third file looks like this asteroids.for_each(HERE_THE_FUNCTION_POINTER); asteroids is the declared List<Asteroid> and the function comes from the template.

So I really have no idea how to solve that and it's on the last minuites :( I hope you can help me so far. All the QNA's I have looked up didnt help just random compiler errors.

PS: I'm not allowed to change any declarations..

Thanks so far.

Method to Call:

void Asteroid::render()
{
// Compute transformation matrix
computeMatrix();

// Push matrix and set transformation and scaling
glPushMatrix();
glMultMatrixf(m_transformation);
glScalef(m_scale, m_scale, m_scale);
if(m_mesh)
{
    m_mesh->render();
}
glPopMatrix();
}

Method wich should call render():

template <typename T>
void List<T>::for_each(void(*do_something)(T item))
{
Node* temp = this->m_list;

while (temp->next != NULL)
{
    if (this->m_list->next != NULL)
    {
        do_something(temp->data);
        temp = temp->next;
    }
}
}

Executing code part:

AsteroidField::AsteroidField(int quantity, string basePath) :
m_basePath(basePath)
{
// Generate asteroids
asteroids = List<Asteroid>();
Randomizer* random = Randomizer::instance();

for(int i = 0; i < quantity; i++)
{
   TriangleMesh* mesh = TriangleMeshFactory::instance().getMesh(m_basePath + "asteroid.3ds");

   float size = random->getRandomNumber(1,5);
   Vertex<float> pos = random->getRandomVertex(5000);
   Asteroid asteroid = Asteroid::Asteroid(mesh, pos, size);
   asteroids.insert(asteroid);
}

}

AsteroidField::~AsteroidField()
{
asteroids.for_each(Asteroid::~Asteroid());
}


void AsteroidField::render()
{
// TODO: Call render for all asteroids
asteroids.for_each(*render());
}
Criska
  • 89
  • 1
  • 8

1 Answers1

1

Consider the signature:

template <typename T>
void List<T>::for_each(void(*do_something)(T item))

do_something here is a void function that takes a T. But your render() is not a free function, it's a class method. Its signature is void (Asteroid::*)(), which does not match. What we need is an intermediary step. Some function that takes an Asteroid* and calls render() on it:

void free_render(Asteroid* a) { a->render(); }

That function matches the required signature (with T = Asteroid*), and is something you can pass into for_each:

asteroids.for_each(free_render);

note that you will have to make sure you're using a List<Asteroid*> - which you should be doing anyway if render is a virtual method.

In C++11, we could use a lambda instead:

void AsteroidField::render()
{
    asteroids.for_each(+[](Asteroid* a){ a->render(); }
    //                ^^^^
    // see: http://stackoverflow.com/questions/18889028/a-positive-lambda-what-sorcery-is-this
}
Barry
  • 286,269
  • 29
  • 621
  • 977
  • OK. Actually I get the error: expected expression `asteroids.for_each(+[](Asteroid* a)){ a->render(); }` The error is at this [ bracket – Criska Jan 05 '15 at 03:36
  • @Criska Are you using C++11? That's only valid for the new standard (my answer originally omitted the 11 part...). – Barry Jan 05 '15 at 03:37
  • Let me have a look to the CMakeFile EDIT: can't find anything about that and I haven't worked on with that.. I think I commit it with error and hope there are enough point .. BUT THANKS FOR YOU HELP! I BELIEVE IT'S CORRECT – Criska Jan 05 '15 at 03:38