vector::cbegin (C++11) |
vector::cend (C++11) |
vector::crbegin (C++11) |
vector::crend (C++11) |
operator!=operator<operator>operator<=operator>=operator<=> (until C++20)(until C++20)(until C++20)(until C++20)(until C++20)(C++20) |
|
erase_if(std::vector) (C++20) |
|
|
|
|
| (1) | |
); | | (until C++17) |
) noexcept(noexcept(Allocator())); | | (since C++17) (constexpr since C++20) |
| (2) | |
vector( const Allocator& alloc ); | | (until C++17) |
vector( const Allocator& alloc ) noexcept; | | (since C++17) (constexpr since C++20) |
| (3) | |
vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator() ); | | (until C++11) |
size_type count, const T& value, const Allocator& alloc = Allocator() ); | | (since C++11) (constexpr since C++20) |
| (4) | |
vector( size_type count ); | | (since C++11) (until C++14) |
vector( size_type count, const Allocator& alloc = Allocator() ); | | (since C++14) |
< class InputIt > vector( InputIt first, InputIt last, const Allocator& alloc = Allocator() ); | (5) | (constexpr since C++20) |
const vector& other ); | (6) | (constexpr since C++20) |
const vector& other, const Allocator& alloc ); | (7) | (since C++11) (constexpr since C++20) |
vector&& other ); | (8) | (since C++11) (noexcept since C++17) (constexpr since C++20) |
vector&& other, const Allocator& alloc ); | (9) | (since C++11) (constexpr since C++20) |
<T> init, const Allocator& alloc = Allocator() ); | (10) | (since C++11) (constexpr since C++20) |
template< <T> R > constexpr vector( , R&& rg, const Allocator& alloc = Allocator() ); | (11) | (since C++23) |
| | |
Constructs a new container from a variety of data sources, optionally using a user supplied allocator alloc .
This constructor has the same effect as vector(static_cast<size_type>(first), static_cast<value_type>(last), a) if is an integral type. | (until C++11) |
This overload participates in overload resolution only if satisfies , to avoid ambiguity with the overload (3). | (since C++11) |
The allocator is obtained as if by calling <allocator_type>::select_on_container_copy_construction( other.get_allocator()). | (since C++11) |
During , only the first argument contributes to the deduction of the container's template parameter. | (since C++23) |
Parameters Complexity Exceptions Notes Example Defect reports See also |
[ edit ] Parameters
alloc | - | allocator to use for all memory allocations of this container |
count | - | the size of the container |
value | - | the value to initialize elements of the container with |
first, last | - | the range first last to copy the elements from |
other | - | another container to be used as source to initialize the elements of the container with |
init | - | initializer list to initialize the elements of the container with |
rg | - | a , that is, an whose elements are convertible to |
[ edit ] Complexity
- If first and last are both forward, bidirectional or random-access iterators,
- The copy constructor of T is only called N times, and
- No reallocation occurs.
- Otherwise ( first and last are just input iterators),
- The copy constructor of T is called O(N) times, and
- Reallocation occurs O(log N) times.
- If R models ranges::forward_range or ranges::sized_range ,
- Initializes exactly N elements from the result of dereferencing successive iterators of rg , and
- Otherwise ( R models input range),
- The copy or move constructor of T is called O(N) times, and
[ edit ] Exceptions
Calls to Allocator :: allocate may throw.
[ edit ] Notes
After container move construction (overload (8) ), references, pointers, and iterators (other than the end iterator) to other remain valid, but refer to elements that are now in * this . The current standard makes this guarantee via the blanket statement in [container.reqmts]/67 , and a more direct guarantee is under consideration via LWG issue 2321 .
The overload (4) zeroes out elements of non-class types such as int , which is different from the behavior of new[] , which leaves them uninitialized. To match the behavior of new [ ] , a custom Allocator::construct can be provided which leaves such elements uninitialized.
Note that the presence of list-initializing constructor (10) means list initialization and direct initialization do different things:
macro | Value | Std | Feature |
| 202202L | (C++23) | construction and insertion; overload ( ) |
[ edit ] Example
[ edit ] defect reports.
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
| C++98 | overload (5) allowed up to 2N copy constructor calls in the input iterator case | changed to O(N) calls |
| C++98 | for overload (4), the elements in the container were default constructed | they are value-initialized |
| C++11 | the default constructor is explicit | made non-explicit |
[ edit ] See also
| assigns values to the container (public member function) |
| assigns values to the container (public member function) |
- Recent changes
- Offline version
- What links here
- Related changes
- Upload file
- Special pages
- Printable version
- Permanent link
- Page information
- In other languages
- This page was last modified on 5 November 2023, at 12:01.
- Privacy policy
- About cppreference.com
- Disclaimers
Stack Exchange Network
Stack Exchange network consists of 183 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Vector with move constructor and move assignment operator [closed]
Please verify whether the code for a move constructor and a move assignment operator is correct.
- \$\begingroup\$ This isn't that kind of code review; take the tour , see How to Ask . If you aren't certain it works, test it. \$\endgroup\$ – jonrsharpe Commented Apr 2, 2017 at 8:54
Default constructor
Stop trying to save space like that. THe point of good coding is to make it readable by humans. The computer can read any style so try and make it more maintainable by making it readable.
I would write it like this:
Sure you can use nullptr for the zero sized array. But this seems like a premature optimization. You can make the rest of your code less complicated by never having a null m_pInt . If there is never a null then your code does not need to check for it.
Also currently you have different behavior for:
Constructor
Sure this works. But std::cout is not the only stream you way want to print too
So I would pass a stream to print() . It can default to std::cout . Then you should add an operator<< . As the normal way of printing something is via << .
Note: prefer "\n" to std::endl . The difference is a stream flush. The stream will already flush itself when required. So you adding extra flushes is only going to cause the flushes to be less optimal.
Copy Constructor
Move constructor.
Yes that works. But you should also mark the move constructor as noexcept . The standard containers have optimizations that can be applied if they know tour class will not throw when being moved. Otherwise they have to fallback to copying to provide the strong exception guarantee.
The standard technique is to use swap though. It makes it look and behave just like move assignment. See below.
Copy Assignment
Yes the test for self assignment looks like a good optimization.
BUT its not. Self assignment happens so rarely (in fact basically never in real code) that what you are doing is pesimizing the normal flow and as a result will make your code slower. You do need to cope with self assignment but because it is so rare you don't need to worry that it is not the optimal path.
The second issue I have here is that you destroy the local data before you have a copy of the new data ready.
If something goes wrong in the rest of your code then you will be unable to roll back the state and thus can not provide the strong exception guarantee. When copying an object it should happen in three distict phases.
So your Copy assignment should look like this:
If you look carefully at those three stages. Stage 1 looks like the constructor and stage 3 looks like the destructor and stage 2 looks like a standard swap function so we can simplify the above to exactly that:
This is called the copy and swap idiom.
Move Assignment
Again the pesimizing test for self assignment.
The standard move assignment is to swap the source and the destination. This has a couple of benefits.
- You don't call delete (and thus don't invoke the destructor). Thus it is potentially faster.
- Because you did not delete the data there is an opportunity for it to be reused.
- If the source is going out of scope it will invoke its destructor and destroy your data but it will be done after the completion of your object thus giving you strong exception guarantee. Thus allowing you to make your assignment operator noexcept.
Standard Move Assignment
I wrote a series of posts about all this.
Vector - Resource Management Allocation Vector - Resource Management Copy Swap Vector - Resize Vector - Simple Optimizations Vector - the Other Stuff
- \$\begingroup\$ Hi. What do you mean by "Stop trying to save space like that." regarding the code MyVector():m_Size(0), m_pInt(nullptr) { } ? What would you write instead if this was the only constructor? \$\endgroup\$ – krismath Commented May 1, 2017 at 21:20
- 2 \$\begingroup\$ @krismath: One initialization per line. The point is to write readable code not try and squeeze as many operations onto a single line as you can. Updating answer with how I would write it. \$\endgroup\$ – Loki Astari Commented May 1, 2017 at 23:03
- \$\begingroup\$ MyVector() could be noexcept if you allow for m_pInt being nullptr . That's worth the hassle easily. \$\endgroup\$ – Deduplicator Commented May 1, 2017 at 23:16
- 1 \$\begingroup\$ @Deduplicator Not sure a noexcept default constructor buys you anything. Are there any optimizations in the STL this will enable? If it does not gain you anything then why add the extra complexity to the rest of your code. Especially when it adds two different meanings for basically the same declaration MyVector x; /* nullptr but size 0*/ and MyVector y(0); /* Not nullptr but size 0*/ \$\endgroup\$ – Loki Astari Commented May 1, 2017 at 23:31
- \$\begingroup\$ Fantastic answer. 1. I wonder why didn't you add m_pInt = nullptr in the destructor after deleting it. Omission? 2. In the ctor: MyVector(int x = 0) : m_size(0) . I believe you wanted to say m_size(x) here right? 3. I always tend to use {} instead of () for initialization of objects because it prevents widening and is more readable (doesn't look like a function call). \$\endgroup\$ – KeyC0de Commented Oct 19, 2018 at 3:47
Not the answer you're looking for? Browse other questions tagged c++ c++11 memory-management vectors or ask your own question .
- The Overflow Blog
- The world’s largest open-source business has plans for enhancing LLMs
- Looking under the hood at the tech stack that powers multimodal AI
- Featured on Meta
- Join Stack Overflow’s CEO and me for the first Stack IRL Community Event in...
- User activation: Learnings and opportunities
Hot Network Questions
- My one-liner 'delete old files' command finds the right files but will not delete them
- Was the total glaciation of the world, a.k.a. snowball earth, due to Bok space clouds?
- What does the intercept mean in a model where the predictor is substance use at baseline and the outcome is substance use over time?
- "00000000000000"
- Raster to polygon in QGIS - How to Poligonize using a limit of vertices
- Rules on Feats When Creating Custom Backgrounds with Player's Handbook (2024)
- Understanding “Your true airspeed will be the same, but your airspeed as opposed to the ground is much faster.” Bhutan Paro International Airport PBH
- Get the size (height, width and S=height*width in em) of the displayed image and draw it
- Fantasy novel where a brother and sister go to a fantasy and travel with a one-armed warrior
- Smallest prime q such that concatenation (p+q)"q is a prime
- Use the lower of two voltages when one is active
- Why is consciousness deemed to be an entity of some kind or concept when it may simply be the act of observing objective reality through the mind?
- How is AC and DC defined?
- Why is 'это' neuter in this expression?
- Is this a scammer or not
- Is it ethical to request partial reimbursement to present something from my previous position?
- CX and CZ commutation
- Could a Gamma Ray Burst knock a Space Mirror out of orbit?
- Need help in tikzpicture
- How can "chemical-free" surface cleaners work?
- Is internal energy depended on the acceleration of the system?
- Can noun phrases have only one word?
- What is the best way to protect from polymorphic viruses?
- Are There U.S. Laws or Presidential Actions That Cannot Be Overturned by Successor Presidents?
- Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
- Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
- OverflowAI GenAI features for Teams
- OverflowAPI Train & fine-tune LLMs
- Labs The future of collective knowledge sharing
- About the company Visit the blog
Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Get early access and see previews of new features.
Copying std::vector: prefer assignment or std::copy?
I have two vectors:
And now I need to copy v1 to v2 . Is there any reason to prefer
std::copy (v1.begin(), v1.end(), v2.begin());
(or vice versa)?
- 7 Assignment operator will do the right thing. The way you've written copy , it'll mess up if v1 is larger than v2 . – jrok Commented Feb 20, 2013 at 10:36
- 5 If v1 is not required after the copy you could just v2.swap(v1); . – hmjd Commented Feb 20, 2013 at 10:38
- 1 Write what you want to do. If you want to assign one vector to another, write that. – Alex Chamberlain Commented Feb 20, 2013 at 10:52
6 Answers 6
Generally I would strongly prefer v2 = v1 :
- It is shorter and makes the intent more clear
- std::copy won't work if v2 doesn't have the same length as v1 (it won't resize it, so it will retain some of the old elements best case ( v2.size() > v1.size() and overwrite some random data used elsewhere in the program worst case
- If v1 is about to expire (and you use C++11) you can easily modify it to move the contents
- Performancewise assignment is unlikely to be slower then std::copy , since the implementers would probably use std::copy internally, if it gave a performance benefit.
In conclusion, std::copy is less expressive, might do the wrong thing and isn't even faster. So there isn't really any reason to use it here.
- 19 Then, what is std::copy for? – altroware Commented Jul 6, 2015 at 10:27
- 46 @altroware: It's for general copying from one range to another. You can't, for example, use the assignment operator to copy from a std::list to a std::vector , or from one portion of a std::vector to another portion of the same std::vector . – Benjamin Lindley Commented Sep 15, 2015 at 18:10
- 4 What will happen if v1 was allocated on the stack and gets destructed? Does v2 = v1 cause elements of v1 to be copied? – James Wierzba Commented Apr 7, 2016 at 14:57
- Which copy mechanism of the element type is called? In this case of vector<int> , are the integers copied from one vector to the other with operator= , or with int 's copy constructor? – Gauthier Commented Nov 9, 2016 at 8:33
- 2 @james operator= Will do a full deep copy. Idiomatic C++ uses value semantics so copying a vector copies all its elements. The exception is if it’s elements are pointers in which case the pointers are copied. After assignment, the vectors are independent. – Ben Commented Oct 24, 2021 at 1:26
If v2 isn't big enough you'll get a buffer overrun if you use copy as you have.
You can use a back insert iterator which will call push_back on v2 . However this could lead to multiple reallocations depending upon how big v1 is.
You're better off letting vector manage things correctly. The assignment operator does this, as does vector::assign :
I have an inkling that the assignment operator is implemented in terms of vector::assign .
- Mr. Wood, is it possible that you meant v2.assign(v1.begin(), v1.end()) rather than v2.assign(v1.begin(), v2.end())? – Peter Schaeffer Commented Dec 21, 2015 at 3:20
The invocation of std::copy may try to access items beyond the end of the destination vector.
Use assignment.
It's not your job to micro-optimize: that's the library writer's responsibility, and ultimately the compiler's responsibility.
You can make your code arbitrarily fast if it doesn't have to be correct.
In the case of the copy , however, it's rather doubtful whether it even is faster, and it's certainly not correct for the general case.
- 3 I agree with your statements concerning optimization, but it might be worth pointing out that the more information available to the compiler or the library, the better it can do its job. Member functions of std::vector know that they're working on an std::vector , and know how it is implemented. std::copy doesn't have this information. The conclusion is that the member functions can probably do the job better (and certainly not worse). – James Kanze Commented Feb 20, 2013 at 10:38
Assignment, by far. More generally, any time the size of the vector might change, or change the entire contents of the vector, you should prefer member functions. The only time std::copy would be appropriate is if you are only replacing a small range totally within the vector.
It's shorter.
std::copy is mainly meant for copying sections of containers. If you need to copy an entire container, you might as well use the copy constructor.
- If v2 isn't big enough you'll get a buffer overrun. – Open AI - Opting Out Commented Feb 20, 2013 at 10:36
Assignement is clearer and internally uses std::copy (or unitizalized_copy _M_allocate_and_copy depending size and capacity) or so performances are the same.
Your Answer
Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more
Sign up or log in
Post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .
Not the answer you're looking for? Browse other questions tagged c++ stl copy or ask your own question .
- The Overflow Blog
- The world’s largest open-source business has plans for enhancing LLMs
- Looking under the hood at the tech stack that powers multimodal AI
- Featured on Meta
- Join Stack Overflow’s CEO and me for the first Stack IRL Community Event in...
- User activation: Learnings and opportunities
- What does a new user need in a homepage experience on Stack Overflow?
- Announcing the new Staging Ground Reviewer Stats Widget
Hot Network Questions
- Alice splits the bill not too generously with Bob
- What was the document that Paul and Chloe signed with Sabrina?
- Example of a forcing notion with finite-predecessor condition that does not add reals
- Can I install a screw all the way through these threaded fork crown holes?
- meaning of a sentence from Agatha Christie (Murder of Roger Ackroyd)
- What is an apologetic to confront Schellenberg's non-resistant divine hiddenness argument?
- Is it possible/recommended to paint the side of piano's keys?
- Are There U.S. Laws or Presidential Actions That Cannot Be Overturned by Successor Presidents?
- What does the intercept mean in a model where the predictor is substance use at baseline and the outcome is substance use over time?
- Use the lower of two voltages when one is active
- Smoking on a hotel room's balcony in Greece
- A certain solution for Sine-Gordon Equation
- What's the strongest material known to humanity that we could use to make Powered Armor Plates?
- (How) is it possible to let portable communication devices detonate via software?
- Bach's figured bass notation?
- Is there a way to hide/show seams on model?
- A thought experiment regarding elliptical orbits
- how does the US justice system combat rights violations that happen when bad practices are given a new name to avoid old rulings?
- obexpushd not found on Bookworm
- If a mount provokes opportunity attacks, can its rider be targeted?
- 〈ü〉 vs 〈ue〉 in German, particularly names
- Fear of getting injured in Judo
- Hungarian Immigration wrote a code on my passport
- In The Martian, what does Mitch mean when he is talking to Teddy and says that the space program is not bigger than one person?
IMAGES
VIDEO
COMMENTS
A = std::move(B); Now A contains the elements that were previously held by B, and B is now empty. This avoids copying: the internal representation is simply moved from B to A, so this is an O(1) solution. As for C++03, as Prætorian states, you could swap the vectors. There is a specialization of the std::swap function, which takes std::vector ...
std::move() is a cast that produces an rvalue-reference to an object, to enable moving from it. It's a new C++ way to avoid copies. For example, using a move constructor, a std::vector could just copy its internal pointer to data to the new object, leaving the moved object in an moved from state, therefore not copying all the data. This would ...
The move assignment operator is called whenever it is selected by overload resolution, e.g. when an object appears on the left-hand side of an assignment expression, where the right-hand side is an rvalue of the same or implicitly convertible type.. Move assignment operators typically transfer the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors ...
A useful extension of this is that if you want to construct a new vector containing only the subset of items being removed from the original vector, you can do it at construction time, with std::vector<T> v2(std::make_move_iterator(v1.begin() + 7), std::make_move_iterator(v1.end())); immediately followed by the matching v1.erase.And, of course, the initial iterator could be the result of std ...
The move assignment operator was added in C++ 11 to further strengthen the move semantics in C++. It is like a copy assignment operator but instead of copying the data, this moves the ownership of the given data to the destination object without making any additional copies. The source object is left in a valid but unspecified state.
Return value. static_cast < typename std:: remove_reference < T >:: type && > (t) [] NoteThe functions that accept rvalue reference parameters (including move constructors, move assignment operators, and regular member functions such as std::vector::push_back) are selected, by overload resolution, when called with rvalue arguments (either prvalues such as a temporary object or xvalues such as ...
1. std::vector<std::string> vecString;- An empty vector is created with no elements in it. 2. vecString = createAndInsert(); ... In C+, the move assignment operator is used to transfer the ownership of the resources from one object to another when the object is assigned some rvalue references or using std::move. It allows efficient memory ...
In lesson 22.1 -- Introduction to smart pointers and move semantics, we took a look at std::auto_ptr, discussed the desire for move semantics, and took a look at some of the downsides that occur when functions designed for copy semantics (copy constructors and copy assignment operators) are redefined to implement move semantics.. In this lesson, we'll take a deeper look at how C++11 resolves ...
How vector works - copy vs. move. When a vector resizes and needs to transfer existing values to the larger array: does it copy or does it move them? ... Mark the move constructor and assignment as noexcept. For the rest of classes let the compiler generate moves. They will be noexcept assuming only types as above are used.
If std:: allocator_traits < allocator_type >:: propagate_on_container_move_assignment:: value is true, the allocator of * this is replaced by a copy of that of other.If it is false and the allocators of * this and other do not compare equal, * this cannot take ownership of the memory owned by other and must move-assign each element individually, allocating additional memory using its own ...
std::move. In C++11, std::move is a standard library function that casts (using static_cast) its argument into an r-value reference, so that move semantics can be invoked. Thus, we can use std::move to cast an l-value into a type that will prefer being moved over being copied. std::move is defined in the utility header.
The copy assignment (1) copies all the elements from x into the container (with x preserving its contents). The move assignment (2) moves the elements of x into the container (x is left in an unspecified but valid state). The initializer list assignment (3) copies the elements of il into the container. The container preserves its current allocator, except if the allocator traits indicate that ...
This topic describes how to write a move constructor and a move assignment operator for a C++ class. A move constructor enables the resources owned by an rvalue object to be moved into an lvalue without copying. For more information about move semantics, see Rvalue Reference Declarator: &&. This topic builds upon the following C++ class ...
first, last. Input iterators to the initial and final positions in a sequence. The range used is [first,last), which includes all the elements between first and last, including the element pointed by first but not the element pointed by last. The function template argument InputIterator shall be an input iterator type that points to elements of ...
std::vector<T,Allocator>:: assign. Replaces the contents of the container. 1) Replaces the contents with count copies of value value. 2) Replaces the contents with copies of those in the range [first,last). The behavior is undefined if either argument is an iterator into *this. This overload has the same effect as overload (1) if InputIt is an ...
8. I am practicing move semantics and placement new by writing a custom Vector class but I am not confident that I use them right. I would really appreciate some pieces of advice regarding my code. Here is my Vector header. Vector( size_t, const T & ); template < typename InputIterator > Vector( InputIterator, InputIterator ); Vector( const ...
For class types, copy semantics are typically implemented via the copy constructor (and copy assignment operator), which defines how objects of that type are copied. ... First, let's assume std::vector is not move-capable. In that case, the above program makes 4 copies: Constructing the value to be passed copies the initializer list into v1;
constexpr vector (std::from_range_t, R && rg, const Allocator& alloc = Allocator()); (11) (since C++23) Constructs a new container from a variety of data sources, optionally using a user supplied allocator alloc. 1) Default constructor. Constructs an empty container with a default-constructed allocator. 2) Constructs an empty container with the ...
According to c++ reference std::vector has a assign operator which takes a rvalue reference. copy (1) vector& operator= (const vector& x); move (2) vector& operator= ( vector&& x ); initializer list (3) vector& operator= (initializer_list il); Then at line v = a, since a is declared as rvalue reference, the move operator should be invoked.
3. Now you can release the old resources. This is unlikely to go wrong; But even if something goes wrong your object is in a good state. So your Copy assignment should look like this: MyVector& operator=(const MyVector& rhs) {. // Make a copy to temp. std::size_t tSize = rhs.m_Size; int* tInt = new int[tSize];
If v1 is about to expire (and you use C++11) you can easily modify it to move the contents. Performancewise assignment is unlikely to be slower then std::copy, since the implementers would probably use std::copy internally, if it gave a performance benefit. In conclusion, std::copy is less expressive, might do the wrong thing and isn't even faster.