For customized use, I have inherited std::vector to a custom class Vector. For my requirement this public inheritance is ok.
One intention is to avoid making copies of a vector array multiple times, so I decided this custom class to be 'ownership' based.
Vector<A> vA1(100); // vA1 is allocated A[100]
Vector<A> vA2 = vA1; // vA2 refers to original A[100] and ...
// ... vA1 is now blank which is expected
This is how it's implemented for C++03:
template<typename T>
struct Vector : std::vector<T>
{
// ... other constructors
Vector (const Vector ©) // copy constructor
{
this->swap(const_cast<Vector&>(copy)); // <---- line of interest
}
// 'operator =' is TBD (either same as above or unimplemented)
};
Am I breaking any language rule/feature/convention ? Is there anything bad in this code ?
Edit: I have added my new approach in form of answer below (Here is its working demo).
I think what you are looking for are move semantics.
Vector<A> vA1(100); // vA1 is allocated A[100]
Vector<A> vA2 = std::move(vA1); // vA2 refers to original A[100] and ...
// ... vA1 is now blank which is expected
If your compiler doesn't have move semantics support I would suggest you use smart pointers or take a look at boost::move which can emulate move semantics in pre C++11 compilers..
std::shared_ptr<Vector<A>> vA1(new Vector<A>(100)); // vA1 is allocated A[100]
std::shared_ptr<Vector<A>> vA2 = vA1; // vA2 refers to original A[100] and ...
vA1.reset();
// ... vA1 is now blank which is expected
or even simpler:
Vector<A> vA1(100); // vA1 is allocated A[100]
Vector<A> vA2;
vA1.swap(vA2);// vA2 refers to original A[100] and ...
// ... vA1 is now blank which is expected
You should really have a look at using C++11: all the standard containers are movable and are thus resembling your semantics in many cases, namely when it is known that the ownership can be transferred. More precisely, containers get moved rather than copied when returning objects from function or when using a temporary to construct or assign an object. Trying to replicate this mechanism in some way will almost certainly yield unexpected behavior in may cases.
In C++11 the movable semantics are integrated into the language and functions, including constructors and assignments, can be overloaded to behave different depending on whether the object is movable or not.
Your code breaks the conventions that support const-correctness:
const Vector<int> foo(12);
const Vector<int> bar(foo); // UB.
some_function_that_takes_Vector_by_value(bar); // UB.
You might say, "but nobody will ever create a const instance of Vector, so the UB will never happen". In which case, you could at least make your copy ctor take a non-const reference in order to follow the convention that functions shouldn't modify objects taken by const& parameters.
Even then, personally I'd prefer to require the user to "switch on" speed by explicitly swapping, than to create traps like this for them. I'd also prefer to have no copy ctor at all, than one which behaves unlike a normal copy. If people are going to have to bear in mind that Vector cannot actually be copied, then they shouldn't use copy syntax to not-copy it.
The issue of unnecessary copies in C++03 isn't a new one and IMO it doesn't require a novel solution. Many C++ programmers already know how to take advantage of swap and copy elision, and those who don't know how to avoid unnecessary copies are better off learning to do it the normal way, than learning to do it a unique way demanded by your one specific class.
With the insight from comments/answers, I realized that my current approach is not a good idea to deal with the things.
I have come up with a changed designed where I try to simulate the "move" operation using swap() method (consider them interchangeable in this context).
For any class or container, which wants to make faster copying (i.e. move by swapping) should inherit below class (directly copy pasting from the real file):
/*
* An empty CRTP base class for the classes which are allowing move sematics (effectively swap)
* A given class `X` must implement `void swap(X&);` method for the movement (i.e. content swapping)
* For example, `X` is deriving this class (i.e. `class X : public Movable<X> ...`)
* ... below is an illustration for how to transfer contents of an `X` object to another
* `X o1; ... X o2(o1.move()); // contents of o1 is now moved to o2`
*/
template<typename Derived>
class Movable
{
/*
* Empty constructor for normal behavior
*/
public: Movable ()
{}
/*
* Copy constructor which does nothing; without this compiler errors out !
*/
public: Movable (const Movable ©)
{}
/*
* Move constructor which will effectively call `Derived::swap()` method
* After this, the contents of the object will be moved to each other
* For syntactic sugar, it has been made `explicit`
*/
public: explicit Movable (Movable &orig)
{
(*this)(orig);
}
/*
* Moving while Not initializing object, one need to use `operator ()` and not `operator =`
* If `operator =` is used then simply `move()` part will not happen; i.e. below 2 are same:
* `obj1 = obj2.move();` and `obj1 = obj2;`
*/
public: void operator () (Movable &orig)
{
static_cast<Derived*>(this)->swap(static_cast<Derived&>(orig));
}
/*
* This method is called from `Derived` class when move sematics is intended
*/
public: Movable& move ()
{
return *this;
}
};
Here how it's supposed to be deployed:
template<typename T>
struct Vector : std::vector<T>,
Movable<Vector<T> > // inherit as CRTP base
{
// ... other methods
typedef Movable<Vector<T> > Movable_;
Vector (Movable_ &orig) : Movable_(orig) {} // Declare a constructor
};
Here how it's supposed to be used:
Vector<A> vA1(100); // vA1 is allocated A[100]
Vector<A> vA2 = vA1; // normal copying (no change)
vA2 = vA1; // normal assignment (no change)
Vector<A> vA3(vA1.move()); // <------- "moves" contents from 'vA1' to 'vA3'
vA1(vA2.move()); // <------- "moves" contents from 'vA2' to 'vA1'
vA2 = vA3.move(); // normal copying from 'vA3' to 'vA2' ('vA3' unaffected)
Related
I have a class in my C++ code which has its own move constructor. A simplified version is shown here:
class myClass {
//In this example, myClass must manually manage allocating
//and freeing a memory buffer.
char *mem;
//...
//Regular constructor, copy constructor, etc
//...
myClass(myClass &&other) {
//Swap our memory pointer with other's memory pointer
char *tmp = other.mem;
other.mem = mem;
mem = tmp;
}
//...
//Destructor, other member functions, etc.
//...
}
In normal situations, this works fine. However, recently I needed to make a vector of these objects:
vector<myClass> v;
v.reserve(10); //Make space, but do not construct
v.push_back(myClass()); //Problem!
After getting a segfault and stepping through with gdb, I eventually discovered what should have been obvious: if you try to construct an object from an rvalue reference, this can result in using the move constructor on uninitialized memory.
How are you supposed to write a move constructor when it's possible that you're swapping garbage into the other class? Is there some way to detect this?
How are you supposed to write a move constructor when it's possible that you're swapping garbage into the other class? Is there some way to detect this?
An object that is not initialized holds an indeterminate value until assigned another value [basic.indet]/1. You're basically not allowed to do anything with an object holding an indeterminate value except for assigning it a proper value [basic.indet]/2. Since you're not even allowed to look at the value an object holds unless it has been initialized or assigned a value, there cannot possibly be a way to detect whether an object has been initialized just by looking at the object itself (because you're not allowed to even take a look). Thus, strictly speaking, you're actually not just "swapping garbage values into the other class", you're invoking undefined behavior. Garbage being swapped is just how that undefined behavior will typically manifest.
The solution to the problem is simple: Make sure that your pointer is always initialized to a valid value, e.g., nullptr:
class myClass {
//In this example, myClass must manually manage allocating
//and freeing a memory buffer.
char *mem = nullptr;
//...
//Regular constructor, copy constructor, etc
//...
myClass(myClass &&other) {
//Swap our memory pointer with other's memory pointer
char *tmp = other.mem;
other.mem = mem;
mem = tmp;
}
//...
//Destructor, other member functions, etc.
//...
}
Rather than implement the move constructor yourself, consider, e.g., just using a member of type std::unique_ptr and simply relying on the implicitly defined move constructor. For example:
class myClass
{
std::unique_ptr<char[]> mem;
// regular constructor, copy constructor, etc.
myClass(myClass&&) = default;
// other member functions, etc.
};
Don't swap the pointers in the constructor. That's not how you write move constructors. Swapping is for move-assignment, when both objects are live.
Constructors exist to initialize an object. As such, the memory they start with is always in the "uninitialized" state. So unless you initialize a member (or it has a default constructor that initializes it for you), the member's value will start uninitialized.
The correct way to handle this is just copy the pointer in the member initializer, then null out the other one.
myClass(myClass &&other) : mem(other.mem) {
other.mem = nullptr;
}
Or, with C++14 (and C++20 with a constexpr version), you can exchange the value:
myClass(myClass &&other)
: mem(std::exchange(other.mem, nullptr))
{}
I am working with writing the big five(copy constructor, copy assignment operator, move constructor, move assignment operator, destructor). And I've hit a bit of a snag with the copy constructor syntax.
Say I have a class foo that has the following private members:
template<class data> // edit
class foo{
private:
int size, cursor; // Size is my array size, and cursor is the index I am currently pointing at
data * dataArray; // edit
}
If I were to write a constructor for this of some arbitrary size X it would look like this.
template<class data> // edit
foo<data>::foo(int X){
size = X;
dataArray = new data[size];
cursor = 0; // points to the first value
}
Now if I wanted to make a copy constructor of another object called bar I'd need to make the following:
template<class data> // edit
foo<data>::foo(foo &bar){
foo = bar; // is this correct?
}
Assuming I have the overloaded = from the code below:
template<class data> // edit
foo<data>::operator=(foo &someObject){
if(this != someObject){
size = someObject.size;
cursor = someObject.cursor;
delete[] dataArray;
dataArray = new data[size];
for(cursor = 0; cursor<size-1;cursor++)
dataArray[cursor] = someObject.dataArray[cursor];
}
else
// does nothing because it is assigned to itself
return *this;
}
Is my copy constructor correct? Or should foo = bar instead be *this = bar ?
I'm still new to templated constructors so if I made any errors in the code please let me know I will correct it.
EDIT 1: Thanks to the answer provided below by Marcin I have made some edits to the code above to make it more syntatically correct and commented them with //edit they are summarized in the list below:
previously template<classname data>, which is incorrect must be template <typename data> or template <class data> for functions and classes respectively.
previously int*dataArray; this missuses the template and should be data* dataArray;
The best way to achieve what you want is to use a class that already handles assignment, copying and moving, taking care of its memory management for you. std::vector does exactly this, and can directly replace your dynamically allocated array and size. Classes that do this are often referred to as RAII classes.
Having said that, and assuming this is an exercise in correctly implementing the various special member functions, I'd suggest that you proceed via the copy and swap idiom. (See What is the copy and swap idiom? on SO, for more details and commentary). The idea is to define the assignment operation in terms of the copy constructor.
Start with the members, constructor and destructor. These define the ownership semantics of the members of your class:
template <class data>
class foo {
public:
foo(const size_t n);
~foo();
private:
size_t size; // array size
size_t cursor; // current index
data* dataArray; // dynamically allocated array
};
template <class data>
foo<data>::foo(const size_t n)
: size(n), cursor(0), dataArray(new data[n])
{}
template <class data>
foo<data>::~foo() {
delete[] dataArray;
}
Here, memory is allocated in the constructor and deallocated in the destructor.
Next, write the copy constructor.
template <class data>
foo<data>::foo(const foo<data>& other)
: size(other.size), cursor(other.cursor), dataArray(new data[other.size]) {
std::copy(other.dataArray, other.dataArray + size, dataArray);
}
(along with the declaration, foo(const foo& other); inside the class body).
Notice how this uses member initialiser lists to set the member variables to the values in the other object. A new allocation is performed, and then in the body of the copy constructor you copy the data from the other object into this object.
Next comes the assignment operator. Your existing implementation has to perform a lot of manipulation of pointers, and isn't exception safe. Let's look at how this could be done more simply and more safely:
template <class data>
foo<data>& foo<data>::operator=(const foo<data>& rhs) {
foo tmp(rhs); // Invoke copy constructor to create temporary foo
// Swap our contents with the contents of the temporary foo:
using std::swap;
swap(size, tmp.size);
swap(cursor, tmp.cursor);
swap(dataArray, tmp.dataArray);
return *this;
}
(along with the declaration in-class, foo& operator=(const foo& rhs);).
[-- Aside: You can avoid writing the first line (explicitly copying the object) by accepting the function argument by value. It's the same thing, and might be more efficient in some cases:
template <class data>
foo<data>& foo<data>::operator=(foo<data> rhs) // Note pass by value!
{
// Swap our contents with the contents of the temporary foo:
using std::swap;
swap(size, rhs.size);
swap(cursor, rhs.cursor);
swap(dataArray, rhs.dataArray);
return *this;
}
However, doing so may cause ambiguous overloads if you also define a move assignment operator. --]
The first thing this does is create a copy of the object being assigned from. This makes use of the copy constructor, so the details of how an object is copied need only be implemented once, in the copy constructor.
Once the copy has been made, we swap our internals with the internals of the copy. At the end of the function body, the tmp copy goes out of scope, and its destructor cleans up the memory. But this isn't the memory that was allocated at the beginning of the function; it's the memory our object used to hold, before we swapped our state with the temporary.
In this way, the details of allocating, copying and deallocating are kept where they belong, in the constructors and the destructor. The assignment operator simply copies and swaps.
This has a further advantage, over and above being simpler: It's exception safe. In the code above, an allocation error could cause an exception to be thrown while creating the temporary. But we haven't modified the state of our class yet, so our state remains consistent (and correct) even when the assignment fails.
Following the same logic, the move operations become trivial. The move constructor must be defined to simply take ownership of the resource and leave the source (the moved-from object) in a well-defined state. That means setting the source's dataArray member to nullptr so that a subsequent delete[] in its destructor doesn't cause problems.
The move assignment operator can be implemented similarly to the copy assignment, although in this case there's less concern with exception safety since you're just stealing the already-allocated memory of the source object. In the complete example code, I opted to simply swap the state.
A complete, compilable-and-runnable example can be seen here.
Your foo class does not internally use data template parameter. I suppose you wanted to use it here:
int * dataArray; // should be: data * dataArray;
You also are not allowed to use classname keyword but typename or class. You have also lots of other compile errors in your code.
Your copy constructor is wrong, it will not compile:
foo = bar; // is this correct? - answer is NO
foo is a class name in this context, so your assumption is correct. *this = someObject this would work (with additional fixes, at least dataArray must be set to nullptr), but your class variables would be default constructed first by copy constructor only to be overwritten by assignment operator, so its quiet non efficent. For more read here:
Calling assignment operator in copy constructor
Is it bad form to call the default assignment operator from the copy constructor?
If I understand correctly postblit constructor in D starts from bitwise copy (always), then there is user-defined body of it.
But when I look at the body of postblit constructor it is very similar to C++ copy constructor, the only difference is in C++ the source is some object, when in D is this (itself).
Am I correct?
Eh, close. I think you have a pretty good handle on it, but to spell it out:
a = b; (iff a and b are both the same type, a struct) translates into:
memcpy(&a, &b, b.sizeof); // bitwise copy
a.__postblit(); // call the postblit on the destination only (iff this(this) is defined on the type!)
So you don't have to explicitly assign any variables in the postblit (they are all copied automatically) and also cannot use it to implement move semantics (you don't have access to the source).
The place I most often use the postblit is when the struct is a pointer to another object, so I can increase the refcount:
struct S {
SomeObject* wrapped;
this(this) { if(wrapped) wrapped.addReference(); }
~this() { if(wrapped) wrapped.releaseReference(); }
}
This only works with references since otherwise you'd be incrementing a copy of the variable!
You can (but shouldn't) also use it to perform deep copies:
struct S {
string content;
this(this) { content = content.idup; }
}
But that's actually a bad idea since struct assignment is supposed to be universally cheap in D and deep copies aren't cheap. There's also generally no need anyway, since the garbage collector handles cases like double free where you might want this in C++.
The other case where I use it a lot in D is actually to disable it:
struct S {
#disable this(this);
}
S a, b;
a = b; // compile error, b is not copyable
That's different than just not implementing a postblit at all, which leaves you with the automatic implementation of memcpy. This makes assignment an outright compile error, which you can use to funnel the user toward another method, for move semantics for example:
struct S {
int* cool;
#disable this(this);
S release() { auto n = cool; cool = null; return S(cool); }
}
Since a=b is prohibited, we can now force the user to use the .release method when they want to reassign it which does our moving.
I understand if you wish to pass a vector of MyClass objects and it is a temporary variable, if there is a move constructor defined for MyClass then this will be called, but what happens if you pass a vector of boost::shared_ptr<MyClass> or std::shared_ptr<MyClass>? Does the shared_ptr have a move constructor which then call's MyClass's move constructor?
if there is a move constructor defined for MyClass then this will be called
Usually not. Moving a vector is usually done my transferring ownership of the managed array, leaving the moved-from vector empty. The objects themselves aren't touched. (I think there may be an exception if the two vectors have incompatible allocators, but that's beyond anything I've ever needed to deal with, so I'm not sure about the details there).
Does the shared_ptr have a move constructor which then call's MyClass's move constructor?
No. Again, it has a move constructor which transfers ownership of the MyClass object to the new pointer, leaving the old pointer empty. The object itself is untouched.
Yes, std::shared_ptr<T> has a move constructor, as well as a templated constructor that can move from related shared pointers, but it does not touch the managed object at all. The newly constructed shared pointer shares ownership of the managed object (if there was one), and the moved-from pointer is disengaged ("null").
Example:
struct Base {}; // N.B.: No need for a virtual destructor
struct Derived : Base {};
auto p = std::make_shared<Derived>();
std::shared_ptr<Base> q = std::move(p);
assert(!p);
If you mean moving std::vector<std::shared_ptr<MyClass>>. Then even the move constructor of std::shared_ptr won't be called. Because the move operation is directly done on std::vectorlevel.
For example, a std::vector<T> may be implemented as a pointer to array of T, and a size member. The move constructor for this can be implemented as:
template <typename T>
class vector {
public:
/* ... other members */
vector(vector &&another): _p(another._p), _size(another._size) {
/* Transfer data ownership */
another._p = nullptr;
another._size = 0;
}
private:
T *_p;
size_t _size;
}
You can see in this process, no data member of type T is touched at all.
EDIT: More specially in C++11 Standard: §23.2.1. General container requirements (4) there is a table contains requirements on implementations of general containers, which contains following requirements:
(X is the type of the elements, u is an identifier declaration, rv is rvalue reference, a is a container of type X)
X u(rv)
X u = rv
C++ Standard: These two (move constructors) should have constant time complexity for all standard containers except std::array.
So it's easy to conclude implementations must use a way like I pointed above for move constructors of std::vector since it cannot invoke move constructors of individual elements or the time complexity will become linear time.
a = rv
C++ Standard: All existing elements of a are either move assigned to or destroyed a shall be equal to the value that rv had before this assignment.
This is for move assign operator. This sentence only states that original elements in a should be "properly handled" (either move-assigned in or destroyed). But this is not a strict requirement. IMHO implementations can choose the best suited way.
I also looked at code in Visual C++ 2013 and this is the snippet I found (vector header, starting from line 836):
/* Directly move, like code above */
void _Assign_rv(_Myt&& _Right, true_type)
{ // move from _Right, stealing its contents
this->_Swap_all((_Myt&)_Right);
this->_Myfirst = _Right._Myfirst;
this->_Mylast = _Right._Mylast;
this->_Myend = _Right._Myend;
_Right._Myfirst = pointer();
_Right._Mylast = pointer();
_Right._Myend = pointer();
}
/* Both move assignment operator and move constructor will call this */
void _Assign_rv(_Myt&& _Right, false_type)
{ // move from _Right, possibly moving its contents
if (get_allocator() == _Right.get_allocator())
_Assign_rv(_STD forward<_Myt>(_Right), true_type());
else
_Construct(_STD make_move_iterator(_Right.begin()),
_STD make_move_iterator(_Right.end()));
}
In this code the operation is clear: if both this and right operand have the same allocator, it will directly steal contents without doing anything on individual elements. But if they haven't, then move operations of individual elements will be called. At this time, other answers apply (for std::shared_ptr stuff).
Given a class like this:
class Foo
{
const int a;
};
Is it possible to put that class in a vector? When I try, my compiler tells me it can't use the default assignment operator. I try to write my own, but googling around tells me that it's impossible to write an assignment operator for a class with const data members. One post I found said that "if you made [the data member] const that means you don't want assignment to happen in the first place." This makes sense. I've written a class with const data members, and I never intended on using assignment on it, but apparently I need assignment to put it in a vector. Is there a way around this that still preserves const-correctness?
I've written a class with const data members, and I never intended on using assignment on it, but apparently I need assignment to put it in a vector. Is there a way around this that still preserves const-correctness?
You have to ask whether the following constraint still holds
a = b;
/* a is now equivalent to b */
If this constraint is not true for a and b being of type Foo (you have to define the semantics of what "equivalent" means!), then you just cannot put Foo into a Standard container. For example, auto_ptr cannot be put into Standard containers because it violates that requirement.
If you can say about your type that it satisfies this constraint (for example if the const member does not in any way participate to the value of your object, but then consider making it a static data member anyway), then you can write your own assignment operator
class Foo
{
const int a;
public:
Foo &operator=(Foo const& f) {
/* don't assign to "a" */
return *this;
}
};
But think twice!. To me, it looks like that your type does not satisfy the constraint!
Use a vector of pointers std::vector<Foo *>. If you want to avoid the hassle of cleaning up after yourself, use boost::ptr_vector.
Edit: My initial stab during my coffee break, static const int a; won't work for the use case the OP has in mind, which the initial comments confirm, so I'm rewriting and expanding my answer.
Most of the time, when I want to make an element of a class constant, it's a constant whose value is constant for all time and across all instances of the class. In that case, I use a static const variable:
class Foo
{
public:
static const int a;
};
Those don't need to be copied among instances, so if it applied, that would fix your assignment problem. Unfortunately, the OP has indicated that this won't work for the case the OP has in mind.
If you want to create a read-only value that clients can't modify, you can make it a private member variable and only expose it via a const getter method, as another post on this thread indicates:
class Foo
{
public:
int get_a() const { return a; }
private:
int a;
};
The difference between this and
class Foo
{
public:
const int a;
};
is:
The const int gives you assurance that not even the implementation of the class will be able to muck with the value of a during the lifetime of the object. This means that assignment rightfully won't work, since that would be trying to modify the value of a after the object's been created. (This is why, btw, writing a custom operator=() that skips the copy of a is probably a bad idea design-wise.)
The access is different – you have to go through a getter rather than accessing the member directly.
In practice, when choosing between the two, I use read-only members. Doing so probably means you'll be able to replace the value of an object with the value of another object without violating semantics at all. Let's see how it would work in your case.
Consider your Grid object, with a width and height. When you initially create the vector, and let's say you reserve some initial space using vector::reserve(), your vector will be populated with initial default-initialized (i.e. empty) Grids. When you go to assign to a particular position in the vector, or push a Grid onto the end of the vector, you replace the value of the object at that position with a Grid that has actual stuff. But you may be OK with this! If the reason you wanted width and height to be constant is really to ensure consistency between width and height and the rest of the contents of your Grid object, and you've verified that it doesn't matter whether width and height are replaced before or after other elements of Grid are replaced, then this assignment should be safe because by the end of the assignment, the entire contents of the instance will have been replaced and you'll be back in a consistent state. (If the lack of atomicity of the default assignment was a problem, you could probably get around this by implementing your own assignment operator which used a copy constructor and a swap() operation.)
In summary, what you gain by using read-only getters is the ability to use the objects in a vector or any container with value semantics. However, it then falls to you to ensure that none of Grid's internal operations (or the operations of friends of Grid) violate this consistency, because the compiler won't be locking down the width and height for you. This goes for default construction, copy construction, and assignment as well.
I'm considering making the data member non-const, but private and only accessible by a get function, like this:
class Foo
{
private:
int a;
public:
int getA() const {return a;}
};
Is this 'as good' as const? Does it have any disadvantages?
As of c++20, using const member variables are legal without restrictions that had made it virtually unusable in containers. You still have to define a copy assignment member function because it continues to be automatically deleted when a const object exists in the class. However, changes to "basic.life" now allow changing const sub-objects and c++ provides rather convenient functions for doing this. Here's a description of why the change was made:
The following code shows how to define a copy assignment member function which is useable in any class containing const member objects and uses the new functions std::destroy_at and std::construct_at to fulfil the requirement so the new "basic.life" rules. The code demonstrates assignment of vectors as well as sorting vectors with const elements.
Compiler explorer using MSVC, GCC, CLANG https://godbolt.org/z/McfcaMWqj
#include <memory>
#include <vector>
#include <iostream>
#include <algorithm>
class Foo
{
public:
const int a;
Foo& operator=(const Foo& arg) {
if (this != &arg)
{
std::destroy_at(this);
std::construct_at(this, arg);
}
return *this;
}
};
int main()
{
std::vector<Foo> v;
v.push_back({ 2 });
v.push_back({ 1 });
v.insert(v.begin() + 1, Foo{ 0 });
std::vector<Foo> v2;
v2 = v;
std::sort(v2.begin(), v2.end(), [](auto p1, auto p2) {return p1.a < p2.a; });
for (auto& x : v2)
std::cout << x.a << '\n';
}