title: c++ : alternative for Vector of references to avoid copying large data
body: <p>I have spent some time looking for answers but didn't find anything that was satisfactory.</p>
  
  <p>Just interested in how some more seasoned C++ people solve this kind of problem  as now I am doing a little more production related coding than prototyping.</p>
  
  <p>Let say you have a class that has say a unordered_map (hashmap) that holds a lot of data, say 500Mb. You want to write an accessor that returns some subset of that data in an efficient manner.</p>
  
  <p>Take the following, where BigData is some class that stores a moderate amount of data.</p>
  
  <pre><code>Class A
  {
     private:
        unordered_map&lt;string, BigData&gt; m_map;   // lots of data
  
     public:
  
      vector&lt;BigData&gt;   get10BestItems()
      {
          vector&lt;BigData&gt;  results;
          for ( ........  // iterate over m_map and add 10 best items to results
          // ... 
         return results;
      }
  
  };
  </code></pre>
  
  <p>The accessor get10BestItems is not very efficient in this code because it first copies the items to the results vector, then the results vector is copied when the function is returned (copying from the function stack). </p>
  
  <p>You can't have a vector of references in c__ for various reasons, which would be the obvious answer:</p>
  
  <pre><code>vector&lt;BigData&amp;&gt; results;     // vector can't contain references.
  </code></pre>
  
  <p>You could create the results vector on the heap and pass a reference to that:</p>
  
  <pre><code>vector&lt;BigData&gt;&amp;   get10BestItems()    // returns a reference to the vector
      {
          vector&lt;BigData&gt;  results = new vector&lt;BigData&gt;;   // generate on heap
          for ( ........  // iterate over m_map and add 10 best items to results
              // ... 
         return results;   // can return the reference 
      } 
  </code></pre>
  
  <p>But then you are going to run into memory leak issues if you are not careful. It is also slow (heap memory) and still copies data from the map to the vector.</p>
  
  <p>So we can look back at c-style coding and just use pointers:</p>
  
  <pre><code>vector&lt;BigData*&gt;   get10BestItems()    // returns a vector of pointers
      {
          vector&lt;BigData*&gt;  results ; // vectors of pointers
          for ( ........  // iterate over m_map and add 10 best items to results
          // ... 
         return results;  
      } 
  </code></pre>
  
  <p>But most sources say to  not use pointers unless absolutely necessary. There are options to use smart_pointers and the boost ptr_vector   but I rather try to avoid these if possible.</p>
  
  <p>I do no that the map is going to be static so I am not too worried about bad pointers.  Just one issue if the code will have to be difference to handle pointers. Stylistically this is not pleasant:</p>
  
  <pre><code>const BigData&amp;   getTheBestItem()    // returns a const reference
  {
         string bestID;
         for ( ........  // iterate over m_map, find bestID
         // ... 
         return m_map[bestID] ; // return a referencr to the best item
  }
  
  
  vector&lt;BigData*&gt;   get10BestItems()    // returns a vector of pointers
  {    
          vector&lt;BigData*&gt;  results ; // vectors of pointers
          for_each ........  // iterate over m_map and add 10 best items to results
          // ... 
         return results;  
   };
  </code></pre>
  
  <p>E.g., if you want a single item then it is easy to return a reference. </p>
  
  <p>Finally option is to simply make the Hash-map public and return a vector of keys (in this case strings):</p>
  
  <pre><code>Class A
  {
        public:
  
           unordered_map&lt;string, BigData&gt; m_map;   // lots of data
  
  
  
      vector&lt;string&gt;   get10BestItemKeys()
      {
          vector&lt;string&gt;  results;
          for (........  // iterate over m_map and add 10 best KEYS to results
          // ... 
         return results;
      }
  
  };
  
  
  
  A aTest;
  ... // load data to map
  
  vector &lt;string&gt; best10 =  aTest.get10BestItemKeys();
  for ( .... // iterate over all KEYs in best10
  {
      aTest.m_map.find(KEY);  // do something with item.
      // ...
  } 
  </code></pre>
  
  <p>What is the best solution? Speed is important but I want ease of development and safe programming practices.</p>