1

Please consider the following piece of code:

int main()
{
    typedef boost::ptr_vector<int> ptr_vector;

    ptr_vector vec0;
    vec0.push_back(new int(1));
    vec0.push_back(new int(2));
    vec0.push_back(new int(3));
    vec0.push_back(new int(4));
    vec0.push_back(new int(5));

    ptr_vector::iterator last  = boost::prior(vec0.end()),
                         first = boost::prior(last, 3);

    ptr_vector vec1(first, last); // this will copy '2, 3, 4' to vec1

    struct print
    {
        void operator()(int const& i) {
            std::cout << i.m_i << std::endl;
        }
    };

    std::for_each(vec0.begin(), vec0.end(), print());   // 1, 2, 3, 4, 5
    std::for_each(vec1.begin(), vec1.end(), print());   // 2, 3, 4

    return 0;
}

I don't want to copy the elements into vec1, but sharing in a way that shared_ptr<> provides. My requirements basically are:

  • Sharing the same instances of a range of objects, which are part of a container, in another container instance
  • Don't want to share one instance in more than these two containers
  • Want to be notified when one element is "suddenly" erased from the other container (or at least get check this, e.g. something like shared_ptr::unique())

Both containers are part of the same class. So, they have the same scope and will be destroyed at the same time. The constructor of these class constructs both containers. After construction there won't be any modification to these containers.

Do I need to use a std::vector<> of shared_ptr<> instead or is there any other solution?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
0xbadf00d
  • 17,405
  • 15
  • 67
  • 107

1 Answers1

3

Yes, you should use a vector<shared_ptr<int>>.

Since you're only working with ranges, you could put together a custom solution that keeps track of the ranges and their intersections (for implementing unique.) Then, you could store everything in vector and have the ranges index into that. This would probably be faster (just on account of the avoided cache misses), but it would be more work to implement.

Neil G
  • 32,138
  • 39
  • 156
  • 257
  • 2
    When there is a `scoped_ptr`/`unique_ptr` and `shared_ptr` available, there is indeed no reason to use a `boost::ptr_container`. – rubenvb Jun 17 '11 at 18:35
  • I don't agree. The `boost::ptr_container` are more performant than a `scoped_ptr` and also delete their elements when they are destructed. Please take a look at the boost notes, if you like to know further informations: http://www.boost.org/doc/libs/1_46_1/libs/ptr_container/doc/ptr_container.html – 0xbadf00d Jun 18 '11 at 03:42
  • @FrEEzE2046: For which operation is the performance better when compared with using scoped_ptr or unique_ptr? – Neil G Jun 18 '11 at 04:05
  • smart pointer elements will have a memory-overhead and you need to construct and destroy them. So, why would you prefer that instead of using the more straightforward ptr_container? – 0xbadf00d Jun 18 '11 at 05:25
  • shared_ptr and unique_ptr don't have any such overhead. They should compile to the same code as ptr_container. – Neil G Jun 18 '11 at 05:27
  • That's correct, but why should I prefer this? Don't you agree, that using ptr_container is more straightforward? Why should I rebuild something that already exists? – 0xbadf00d Jun 18 '11 at 12:30
  • @Freeze2046: If ptr_container is a perfect fit for you, then you're right that you should use it. It does add a dependency on boost, which unique_ptr won't. Given the existence of unique_ptr, @rubenvb has a point that long term I doubt ptr_vector will ever make it into the standard. – Neil G Jun 18 '11 at 14:59