Hello, I have a vector of smart pointers and I'd like to NULL smart pointers in reverse order. Smart pointers are done with boost::shared_ptr<>, this is the code:

// List of pointers
typedef boost::shared_ptr<int> TSmart;
std::vector<TSmart> Vec;
// Make sure that everything is NULL
std::transform( Vec.rbegin(), Vec.rend(), TSmart());

I get errors for this one. What am I doing wrong? I tried to use boost::bind

std::transform( Vec.rbegin(), Vec.rend(), boost::bind<TSmart>(TSmart()));

But I still get errors. I do not want to use boost::lambda there. What is the proper way to do that?
Thanks

Dani AI

Generated

The compile error is because std::transform expects an output iterator as its third parameter, not a value. The overload you tried (two iterator args plus a TSmart() value) does not exist. ' approach works because it supplies a proper destination iterator and a functor, but there are simpler and clearer ways to null every boost::shared_ptr in a vector.

A concise way to set every element to a null shared_ptr (no per-element functor needed) is std::fill:

std::fill(Vec.begin(), Vec.end(), TSmart());

If the order in which the pointed-to objects are destroyed matters (you asked for reverse order), iterate with reverse iterators and call reset() on each element:

for (auto it = Vec.rbegin(); it != Vec.rend(); ++it)
    it->reset();   // or *it = TSmart();

You can also use an algorithm with a member-call binder if you prefer:

std::for_each(Vec.rbegin(), Vec.rend(), boost::bind(&TSmart::reset, _1));

Notes and cautions:

  • std::fill copies the provided value into each slot; using TSmart() gives an empty smart pointer for each element.
  • Resetting a shared_ptr only destroys the pointed object once its last owner is gone; other copies elsewhere prevent immediate destruction.
  • Cyclic references will keep objects alive even after resets; use weak_ptr to break cycles (see weak/shared_ptr docs).

Useful references: std::fill, std::transform, std::for_each, and the shared_ptr discussion on ownership and cycles (see the shared/weak pointer docs).

Recommended Answers

All 2 Replies

Well, if you use vec.size() surely the vector is empty when you're trying to null everything... right? Also, doesn't transform take four parameters?

Anyway, something like this should work:

#include <iostream>
#include <vector>
#include <algorithm>

#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>

template <class ty>
  class nullify {
  private:
  public:
    ty operator ( ) ( ty &elem ) {
      elem.reset();
      return elem;
    }
  };

int main() {
  // List of pointers
  typedef boost::shared_ptr<int> TSmart;

  std::vector<TSmart> Vec;

  // Make sure that everything is NULL
  std::transform( 
    Vec.begin(), 
    Vec.end(), 
    Vec.begin(), 
    nullify<TSmart>() );

  return 0;
}

Thanks a lot, twomers. Your solution works!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.