Do all STL containers return their items by reference?

I am studying STL these days, and I was wondering if STL containers are returned by reference?

eg:

vector.first(); map[key]; *vector.begin(); Or any possible return that ends with element (or value type) of container 

eg:

 std::vector<int> elements; elements.push_back(20); elements[0]=60; // this will also change the value elements.front() = 23; // even the functions also behave same way like subscript operator 

In this case, all the containers? Or are there some points to consider that I did not show?

+7
source share
4 answers

It is not possible to return the added item or container as a member function of the container in safe mode. STL containers basically provide a “strong guarantee." The return of the managed item or container will make it impossible to provide a reliable guarantee (this will provide only a “basic guarantee”). An explanation of these conditions is provided on the boost website for Exception-Security in Common Components . See below the Boost website .

  • Basic guarantee: preservation of component invariants and resource leakage.
  • Strong guarantee: the operation completed successfully or threw an exception, leaving the state of the program exactly as it was before the start of the operation.
  • Throw-Free Prevention: The operation will not throw an exception.

Back to the topic: In this previous SO answer , the reason is that returning something could cause a constructor call that might throw an exception, But the function has already exited, so it successfully completed its main task, but still threw an exception. which is a violation of a strong guarantee. You may be thinking, "Well, then we will return by reference!" Although this sounds like a good solution, it is not entirely safe. Consider the following example:

 MyClass bar = myvector.push_back(functionReturningMyClass()); // imagine push_back returns MyClass& 

However, if the copy-assignment operator throws, we do not know whether push_back succeeded or not, indirectly violating the strong guarantee. Although this is not a direct violation. Of course, using MyClass& bar = //... instead would fix this problem, but it would be rather inconvenient for the container to get into an undefined state, just because someone forgot &.

A similar argument is that std::stack::pop() does not return a pop-up value. Instead, top( ) returns the highest value in a safe way. after calling top, even when a copy constructor or copy assignment constructor is created, you still know that the stack has not changed.

+13
source

All types of containers (sequence, associative) are designed to provide a consistent interface (if possible). This makes learning them relatively easy and using them even easier (as long as you have studied them correctly!))

So, for example, operator[] for all containers will return a reference to the object indexed (in the case of associated containers, it will be created first). For sequence containers, there is an interesting point about border checking, but that's a different story. Similarly, if you perform any other general operation ( insert , etc.), It will have a similar interface. Your favorite link will usually provide all the information you need.

+2
source

Yes, the overloaded operator [] for stl containers returns a link. Therefore, in the above examples, the values ​​in m and elements will be changed.

From http://www.cplusplus.com/reference/stl/vector/operator%5B%5D/ :

Definition or operator [] for a vector:

 reference operator[] ( size_type n ); const_reference operator[] ( size_type n ) const; 

Where 'The reference and const_reference member const_reference are reference types for vector container elements (usually denoted by T& and const T& respectively in most storage distribution models).'

Edit: keep in mind that not all stl containers have an overloaded operator [] . Those that do not: list , multimap , multiset , priority_queue , queue , set and stack .

+2
source

std::vector<bool> allowed to return something other than a reference to bool (if you really mean the standard library, not SGI STL). But it is also usually regarded as a mistake that does not deserve to be called a container.

+1
source

All Articles