Question

I have the following code:

// For each trigger model (_1) (which is just a CString), do:
//    m_triggers.push_back(triggers.GetTrigger(static_cast<char const*>(_1)))
boost::transform(
   model.Triggers(),
   std::back_inserter(m_triggers),
   phx::bind(&CTriggerController::GetTrigger, phx::ref(triggers),
      phx::static_cast_<char const*>(_1)));

m_triggers is a vector of pointers to trigger objects:

std::vector<CTrigger*> m_triggers;

If the call to CTriggerController::GetTrigger() returns NULL (which means no trigger by that name could be found), I do not want to push anything to my m_triggers vector.

Is there a straightforward way of doing this through some minor modification to my code above?

I'm using Boost 1.55.0 on MSVC9 (C++03 only)

Was it helpful?

Solution

You can use Boost.Range to transform and filter at the same time.

#include <vector>
#include <iostream>

#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>

int main()
{
  int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  std::vector<int> out;
  using boost::adaptors::filtered;
  using boost::adaptors::transformed;
  boost::copy(data | transformed([](int x) { return x + 1; }) 
                   | filtered([](int x) { return x % 2 == 0; }),
              std::back_inserter(out));
  for(auto x : out) {
    std::cout << x << std::endl;
  }

  return 0;
}

And something that should fit your use-case better:

boost::copy(
   model.Triggers() | transformed(phx::bind(&CTriggerController::GetTrigger, phx::ref(triggers),
                        phx::static_cast_<char const*>(_1)))
                    | filtered(phx::val(phx::placeholders::_1)),
   std::back_inserter(m_triggers)
   );

OTHER TIPS

First copy to a temporary container using std:remove_copy_if with a predicate to remove when GetTrigger() == NULL, then transform.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top