How to add an object to the <const Obj &> vector?

I am not sure why this will not compile:

std::vector< const Obj& > myVector; void foo(const Obj& obj) { myVector.push_back( obj ); } 

Sorry, a bit more information on what I'm trying to achieve: I cannot change the signature of foo without breaking the interface, but I just want to hang on objects that pass through foo. I want to store pointers for them, but I'm confused by the syntax of how to do this.

+4
source share
8 answers

You cannot have a link vector. since the things in the vector must be copyable and assignable, and the links are not one of them. You probably need a pointer vector:

 std::vector< const Obj * > myVector; void foo( const Obj & obj ) { myVector.push_back( & obj ); } 
+15
source

I'm not sure if you can put links in such a container. Use

  std::vector<const Obj *> myVector 

not as semantically equivalent.

+4
source

You cannot use links as types in a vector. You can use raw pointers, smart pointers (boost / std :: tr1 shared_ptr) or other constructs like boost::ref and boost::cref that provide wrappers around simple links to adapt to containers.

+4
source

Vectors only work with type values; you cannot have a link vector.

Part of the reason is that links must be bound to an existing variable as they are created, and they can never be re-linked. In order for the vector to be able to hold 10 elements according to its "default value", it is impossible with a reference type:

 std::vector<const T& obj>(10); // cannot work 

Similarly, you cannot reassign a value to a link (unless you intend to change the value of the original variable), so suddenly myVec[0] = 7 does not work either.

+4
source

Alternatively, you can use boost::ref to store links, but this is similar to saving pointers.

  std::vector< boost::ref< Obj > > myVector; 

According to your changes, if you want to keep pointers, you can simply write something like:

 std::vector < const Obj* > myVector; void foo(const Obj& obj) { myVector.push_back(&obj); } 

If you use boost :: ref or boost :: cref:

 std::vector < boost::cref < Obj > > myVector; void foo(const Obj& obj) { myVector.push_back(boost::cref< Obj >(obj) ); } 

(maybe you can omit the last boost :: cref in the body too, but I don't have a compiler now).

+4
source

C ++ standard in chapat 23.1. Container requirements determine:

3 The type of objects stored in these components must meet the requirements of CopyConstructible types (20.1.3), and the additional requirements of Assignable types.

In other words, type T can be used with standard C ++ containers as a value type if it defines a copy constructor. The concept of CopyConstructible is explained by the standard in the quoted chapater, but the Boost manual clearly explains what the CopyConstructible type means .

The link does not meet this requirement.

+2
source

You cannot store links in an STL container because links are not copied. TR1 contains a link shell if you really need to "simulate" link preservation. Storing smart pointers (e.g. tr1 :: shared_ptr) or object instances is usually better.

+1
source

Besides the problems with links that are the target type for the container, you cannot have const objects as the target type for the container, because the type of objects that are created by the container must be “Assignable” as well as “Assignable”, CopyConstructable ”(23.1 Container Requirements.) Const objects cannot be assigned.

To be assigned, after the operation 't = u t must be equivalent to u , where t is of type t - the type with which the container was created.

However, as mentioned in other answers, you can put pointers to const objects in containers.

+1
source

Source: https://habr.com/ru/post/1299372/


All Articles