Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

STL containers with reference to objects [duplicate]

I know STL containers copy the objects. So say I have a

list<SampleClass> l; 

each time when I do

SampleClass t(...); l.push_back(t); 

a copy of t will be made. If SampleClass is large, then it will be very costly.

But if I declare l as a container of references,

list<SampleClass&> l; 

When I do

l.push_back(t); 

Will it avoid copying the objects?

like image 236
CuriousMind Avatar asked Oct 10 '11 01:10

CuriousMind


People also ask

Are STL containers passed by reference?

@BjörnPollex Yes! I forgot to mention that.

What are the types of STL containers?

In C++, there are generally 3 kinds of STL containers: Sequential Containers. Associative Containers. Unordered Associative Containers.


2 Answers

If you know what you're doing, you can make a vector of references using std::reference_wrapper:

#include <functional> #include <vector>  int main() {   std::vector<std::reference_wrapper<int>> iv;    int a = 12;   iv.push_back(a);  // or std::ref(a)    // now iv = { 12 };    a = 13;    // now iv = { 13 }; } 

Note of course that any of this will come crashing down on you if any of the referred-to variables go out of scope while you're still holding references to them.

like image 121
Kerrek SB Avatar answered Sep 19 '22 11:09

Kerrek SB


Sadly no, it won't compile (with stlport at least). But the alternative, which is to store pointers to your objects in the container, will compile perfectly fine.

This will leave you with a bit of extra syntactic noise around your code - you'll have to new things in order to insert them into your container.

std::list<class_type*> l; l.push_back(new class_type); 

However though the objects now won't be copied, they also won't be automatically cleaned up for you when the list is destructed. Smart pointers will solve this for you, but at the cost of even more syntactic noise. And since you can't put std::auto_ptr's in standard containers because they can't be copied, you have to use their slightly heavier-weight boost cousins, shared pointers.

std::list<boost::shared_ptr<class_type> > l; l.push_back(boost::shared_ptr<class_type>(new class_type)); 

Shared pointed do incur some extra overhead, but it is minimal.

like image 22
Dave Branton Avatar answered Sep 22 '22 11:09

Dave Branton