Ruby blocks, closing Java in C ++

I am developing a program in which I do so much:

void Model::SetCollideMode( const std::string &m )
{
  Body *body;

  std::map<std::string, Body* >::iterator iter;

  for (iter=this->bodies.begin(); iter!=this->bodies.end(); iter++)
  {
    body = iter->second;

    body->SetCollideMode( m );
  }
}

I have several methods like this in several objects that basically apply the property to all of its children. Coming from the world of Ruby, I am dying to do something like:

for_all_bodies{ body->SetCollideMode(m) }

In any case, to make this code more private, for example, or otherwise improve it?

I realize how C ++ works, that it is stack-based, and there is no contextual information to create the ideal closure function (does this require a virtual machine?), But at least it’s better compared to the current repetition of this code at 100 programming times.

+3
source share
5

, .

-, "" :

struct SetCollideModeFunc {
  SetCollideModeFunc(const std::string& m) : m(m) {}
  void operator()(std::pair<std::string, Body*>& p) {
    Body* b = p.second;
    b->SetCollideMode(m);
  }

  const std::string& m;
};

void Model::SetCollideMode( const std::string &m )
{
  std::for_each(bodies.begin(), bodies.end(), SetCollideModeFunc(m));
}

, , . collidemode , , .

Boost.Lambda, inline. , Boost.Lambda, :

std::for_each(bodies.begin(), bodies.end(), _1.second->SetCollideMode(m));

++ 0x lambdas, , , .

, Boost.ForEach , , :

void Model::SetCollideMode(const std::string &m)
{
  BOOST_FOREACH ((std::pair<std::string, Body*> p), bodies) // note the extra parentheses. BOOST_FOREACH is a macro, which means the compiler would choke on the comma in the pair if we do not wrap it in an extra ()
  {
    p.second->SetCollideMode(m);
  }
}
+4

++ 0x . . . , ++, , - , , undefined. ! - , , , .

, ,, , , , .

+5

BOOST_FOREACH ( , ), , , , tr1 bind:

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

void Model::SetCollideMode( const std::string &m )
{
  for_each(bodies.begin(),bodies.end(),
           tr1::bind(&Body::SetCollideMode,
                     tr1::bind(&pair<std::string, Body*>::second, _1), m));
}
+4

Boost.Foreach:

#include <boost/foreach.hpp>

void Model::SetCollideMode(const std::string &m)
{
  typedef pair<std::string, Body*> body_t;
  BOOST_FOREACH (body_t& body, bodies)
  {
    body.second->SetCollideMode(m);
  }
}
+2
source

C ++ does not yet support lambda. I sometimes use this workaround:

#include <boost/bind.hpp>
void Model::SetCollideMode( const std::string &m )
{    
  typedef std::map<std::string, Body* > Bodies;
  struct Helper
  {
      static SetCollideMode(const std::pair<std::string, Body*> & value,
                            const std::string & m)
      {
          value.second->SetCollideMode(m);
      }
  };

  for_each(bodies.begin(),
           bodies.end(),
           boost::bind(Helper::SetCollideMode,_1, m));
}

Only my 2 cents.

+1
source

Source: https://habr.com/ru/post/1710943/


All Articles