How to correctly return a large vector

   vector<Foo*>&         getVectorOfFoo();

I want to provide a list of my Foo objects to others. Is this the best way to do this? Am I returning the link here, and not copying correctly?

Can the caller (accidentally) change this list correctly? Is there any way to avoid this possibility? Can I return a const vector? But they can always modify Foo objects, and I cannot do anything there. 10-20 different people will write code that uses this Foo list.

+5
source share
4 answers

The first does not return a list of pointers.
This makes him doubly incomprehensible regarding the permitted actions.

Boost ( ).
. .

boost::ptr_vector<Foo> const&  getVectorOfFoo();

.

:

#include <boost/ptr_container/ptr_vector.hpp>

class Foo
{
    public:
        void plop()         {}
        void poop() const   {}
};

boost::ptr_vector<Foo> const&  getVectorOfFoo()
{
    static boost::ptr_vector<Foo>  instance;  // Create and fill container with FOO objects.
    instance.push_back(new Foo);
    return instance;
}

int main()
{
    boost::ptr_vector<Foo> const&  value = getVectorOfFoo();  

    value[0].plop();  // Fail. not a const method (comment out this line)
    value[0].poop();
}
+9

, .

typedef, , , vector.

, , YourThing::const_iterator getFooBegin() getFooEnd(). , , , , .

, , , , , , . vector, -const, . , boost.

+2

const.

const vector<Foo *> &getVectorOfFoo();
+1

, const .

But it is still not "perfect" because you need to expose the container to the world, so if you change it, you will also change the user code if the interface is no longer the same.

But there is one last hope:

If you can use lambdas (C ++ 0x), you better provide the for_each algorithm:

class MyThingManager
{
public:

   template< typename FunctorType > // note : could be non-template, in wich case use std::function<>
   void modify_each_thing( FunctorType f ) // if you use std::function, you can put the implementation in the cpp file instead of the header/inline
   {
       // do some checks, or maybe generate a list of Things that you allow to modify

       // then apply the function (here we assume we don't have a separate list - implementation defined for the win!)
       std::for_each( m_things.begin(), m_things.end(), f ); // oh yeah
       // then we can apply anything more we want
       check_everything_is_still_valid();
       notify_the_world();
   }

   // here is a simpler read-only version
   template< typename FunctorType >
   void for_each_thing( FunctorType f ) const { std::for_each( m_things.begin(), m_things.end(), f ); }


   // in case you want the user to know how many things to manipulate
   size_t things_count() const { return m_things;} 



private:

   std::vector<Thing> m_things; // could be any container, that isolated from the algorithm!

};

Using:

 MyThingManager manager;
 manager.for_each_thing( []( const Thing& thing ){ std::cout << "\nA thing : " << thing; } );
+1
source

All Articles