How to use a vector with an object of an instance of a reference type in C ++ 11?

Is it possible to have std :: vector without a copy object (there is a reference instance) in C ++ 11?

struct CanNotCopy { int& intref_; CanNotCopy(int& i) noexcept : intref_(i) {} // How do I make move constructor and operator = ? }; std::vector<CanNotCopy> hoge; // OK hoge.resize(10); // default constructor required int j = 123; hoge[1] = CanNotCopy(j); // copy constructor required 
0
source share
4 answers

From std::vector , describing T :

The requirements for the elements depend on the actual operations performed on the container. Typically, an element type is required to meet the requirements of MoveConstructible and MoveAssignable, but many member functions have more stringent requirements.

CanNotCopy not movable or copied, so it cannot be used as T

A particular solution is to use std::reference_wrapper<CanNotCopy> as the type of element (which can be copied, but not by default), which:

... is a class template that wraps the link in the copy to be assigned to the object. It is often used as a mechanism for storing links inside standard containers (for example, std :: vector or std :: pair), which usually cannot contain links.

For instance:

 std::vector<std::reference_wrapper<CanNotCopy>> hoge; int j = 19; CanNotCopy c(j); hoge.push_back(std::ref(c)); std::cout << hoge[0].get().intref_ << "\n"; 

resize() not available with std::reference_wrapper<CanNotCopy> because it is not constructive by default. However, this solution is fragile, as there are time-dependent references to CanNotCopy and int that are referenced within the CanNotCopy instance, putting the links at risk.

The solution is to use std::unique_ptr<CanNotCopy> as the element type (which is movable and default constructive):

 std::vector<std::unique_ptr<CanNotCopy>> hoge; hoge.resize(5); int j = 19; hoge[1].reset(new CanNotCopy(j)); std::cout << hoge[1]->intref_ << "\n"; 

The dependency of the service life on the int link inside CanNotCopy is still preserved.

+5
source

Straight to enable vector<CanNotCopy> :

 struct CanNotCopy { int& intref_; CanNotCopy (CanNotCopy && from) : intref_(from.intref_) { } }; 

This, of course, will allow you to move objects from and from the vector, but not create copies or create elements created by default. I have no idea about the semantics of the class, in particular, I don’t know what intref_ means. You must also initialize it in standard ctor, so I cannot write this for you.

0
source

This is possible with std::optional / boost::optional . The second requires the use of factories in place to achieve the desired behavior.

0
source

I had the same question that was answered very well here : use std::vector::emplace_back .

0
source

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


All Articles