• Analysis of Algorithms
  • Backtracking
  • Dynamic Programming
  • Divide and Conquer
  • Geometric Algorithms
  • Mathematical Algorithms
  • Pattern Searching
  • Bitwise Algorithms
  • Branch & Bound
  • Randomized Algorithms

std::move in Utility in C++ | Move Semantics, Move Constructors and Move Assignment Operators

Prerequisites:

  • lvalue reference
  • rvalue reference
  • Copy Semantics (Copy Constructor)

References:

In C++ there are two types of references-

  • An lvalue is an expression that will appear on the left-hand side or on the right-hand side of an assignment.
  • Simply, a variable or object that has a name and memory address.
  • It uses one ampersand (&).
  • An rvalue is an expression that will appear only on the right-hand side of an assignment.
  • A variable or object has only a memory address (temporary objects).
  • It uses two ampersands (&&).

Move Constructor And Semantics:

The move constructor was introduced in C++11 . The need or purpose of a move constructor is to steal or move as many resources as it can from the source (original) object , as fast as possible, because the source does not need to have a meaningful value anymore, and/or because it is going to be destroyed in a moment anyway. So that one can avoid unnecessarily creating copies of an object and make efficient use of the resources

While one can steal the resources, but one must leave the source (original) object in a valid state where it can be correctly destroyed.

Move constructors typically “steal” the resource of the source (original) object rather than making several copies of them, and leaves the source object in a “valid but unspecified state”.

The copy constructor uses the lvalue references which are marked with one ampersand (&) while the move constructor uses the rvalue references are marked with two ampersands (&&).

std::move() is a function used to convert an lvalue reference into the rvalue reference. Used to move the resources from a source object i.e. for efficient transfer of resources from one object to another. std::move() is defined in the <utility> header .
template< class T >  typename std::remove_reference<T>::type&& move(T&& t) noexcept;                 (since C++11)(until C++14) template< class T >  constexpr std::remove_reference_t<T>&& move(T&& t) noexcept                       (since C++14)

Example: Below is the C++ program to show what happens without using move semantics i.e. before C++11.

Explanation:

Assuming the program is compiled and executed using a compiler that doesn’t support move semantics. In the main() function,  

1. std::vector<std::string> vecString;- An empty vector is created with no elements in it.  2. vecString = createAndInsert();- The createAndInsert() function is called. 3. In createAndInsert() function-

  • std::vector<std::string> vec;- Another new empty vector named as vec is created.
  • vec.reserve(3);- Reserving the size of 3 elements.
  • std::string str(“Hello”);- A string named as str initialized with a “Hello”.
  • vec.push_back( str );- A string is passed by value into the vector vec. Therefore a (deep) copy of str will be created and inserted into the vec by calling a copy constructor of the String class.
  • A temporary object will be created (str + str) with its own separate memory.
  • This temporary object is inserted into vector vec which is passed by value again means that a (deep) copy of the temporary string object will be created.
  • As of now, the temporary object is no longer needed hence it will be destroyed.

Note: Here, we unnecessarily allocate & deallocate the memory of the temporary string object. which can be optimized (improved) further just by moving the data from the source object. 

  • vec.push_back( str );- The same process as of Line no. 5 will be carried out. Remember at this point the str string object will be last used.
  • Firstly, the string object str will be destroyed because the scope is left where it is declared.
  • Secondly, a local vector of string i.e vec is returned. As the return type of the function is not by a reference. Hence, a deep copy of the whole vector will be created by allocating at a separate memory location and then destroys the local vec object because the scope is left where it is declared.
  • Finally, the copy of the vector of strings will be returned to the caller main() function.
  • At the last, after returning to the caller main() function, simply printing the elements of the local vecString vector.

Example: Below is the C++ program to implement the above concept using move semantics i.e. since C++11 and later. 

Here, in order to use the move semantics. The compiler must support the C++11 standards or above. The story of execution for the main() function and createAndInsert() function remains the same till the line vec.push_back( str );

A question may arise why the temporary object is not moved to vector vec using std::move(). The reason behind it is the push_back() method of the vector. Since C++11 the push_back() method has been provided with its new overloaded version.

The push_back() method takes its parameter by const reference, but since std::vector stores its elements by value, a deep copy of str is created and inserted into the vector. This involves calling the copy constructor of std::string.

Syntax:  

constexpr void push_back(const T& value);                                        (since C++20) void push_back(T&& value);                                                              (since C++11) (until C++20) void push_back(const T& value);                                                        (until C++20) constexpr void push_back(T&& value);                                              (since C++20)
  • A temporary object str + str is created.
  • This temporary object is then passed to vec.push_back(). Since std::vector stores elements by value, it will create a copy of this temporary object.
  • The temporary object is destroyed as it is no longer needed.
  • vec.push_back(std::move(str));-
  • std::move() casts str to an rvalue reference, and push_back() will move the contents of str into the vector, leaving str in a valid but unspecified state.
  • return vec; – This typically involves returning the local vector vec. While a deep copy of the vector would normally be created, modern compilers often use Return Value Optimization (RVO) to eliminate unnecessary copying.

A question may arise while returning the vec object to its caller. As it is not required anymore and also a whole temporary object of a vector is going to be created and also local vector vec will be destroyed, then why std::move() is not used to steal the value and return it.  Its answer is simple and obvious, there is optimization at the compiler level known as (Named) Return Value Object, more popularly known as RVO . 

Some Fallback Of Move Semantics:  

  • It doesn’t make any sense to steal or move the resources of a const object.
  • See constObjectCallFunc() function in the below program
  • See baz() function in the below program
  • See bar() function in the below program

Note: The foo() function have all necessary types of arguments.

Below is the C++ program to implement all the above concepts- 

Summary:  

  • Move semantics allows us to optimize the copying of objects, where we do not need the worth. It is often used implicitly (for unnamed temporary objects or local return values) or explicitly with std::move().
  • std::move() means “no longer need this value” .
  • An object marked with std::move() is never partially destroyed. i.e. The destructor will be called to destroy the object properly.

Please Login to comment...

Similar reads.

  • C++ Programs
  • Competitive Programming
  • Blogathon-2021
  • Constructors
  • Best External Hard Drives for Mac in 2024: Top Picks for MacBook Pro, MacBook Air & More
  • How to Watch NFL Games Live Streams Free
  • OpenAI o1 AI Model Launched: Explore o1-Preview, o1-Mini, Pricing & Comparison
  • How to Merge Cells in Google Sheets: Step by Step Guide
  • #geekstreak2024 – 21 Days POTD Challenge Powered By Deutsche Bank

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

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? It’s more complicated than it should be.

In the previous articles I used ambiguous expressions such as “move/copy” when referring to the transfer of existing values when resizing a vector. This article explains why.

Pre C++11 the vector would copy on resize. That’s not a problem for built-in types like int s that can just be bitwise copied.

But vectors of containers, such as std::vector<std::string> would usually have to copy the values on resize. The library could have done something special about types it knew, such as std::string , but it will have to copy when faced with new types, even as simple as:

some_struct { std::string m0; }; // pre C++11 would copy for resize of // std::vector<some_struct>

Also there are types that hold a resource, which are not copyable. Pre C++11 such types would have private copy operations to prevent accidental copying, but then they could not be stored easily in containers such as std::vector .

<typename T> struct pre_cpp11_ptr { T * ptr; pre_cpp11_ptr(T* raw) : ptr(raw) {} ~pre_cpp11_ptr { delete ptr; } //make copy private, but can't use std::vector<pre_cpp11_ptr<int> > private: pre_cpp11_ptr(const pre_cpp11_ptr &); pre_cpp11_ptr & operator=(const pre_cpp11_ptr &); };

C++ 11 introduces the move semantics.

That means that std::vector<std::string> moves the std::string values instead of copying when it resizes, even if they are inside structures as some_struct above.

Also C++ 11 comes with std::unique_ptr , which can be put in a vector, i.e. std::vector<std::unique_ptr<int>> . The std::unique_ptr values are moved when the vector resizes. Note that you can’t take a copy of a std::vector<std::unique_ptr<int>> as the std::unique_ptr can’t be copied.

So it’s all good, right?

Standardese

It turns out it’s very difficult to determine based on the standard if a values of a vector are moved or copied. For example you might get that the choice depends on the result of !std::is_nothrow_move_constructible_v<T> && std::is_copy_constructible_v<T> .

But then it gets complicated. For example for std::is_move_constructible on which the nothrow version is based has edge cases where it returns true even if there is no move constructor, because types without a move constructor, but with a copy constructor that accepts const T & arguments, satisfy std::is_move_constructible .

Also std::is_copy_constructible returns true for types that cannot be copied e.g. std::vector<std::unique_ptr<int>> . In this case the std::vector has a copy constructor, which actually can’t be instantiated successfully.

Recommended idiom

But all this standardese is irrelevant if types that you might put into a container have a non throwing move constructor. That is a good idiom to follow:

  • For low level classes, e.g. for RAII classes, for your own container classes, ensure you have a non-trowing move which just transfer ownership involving copying of handles/pointers and invalidating the ones at the source of the move. These operations don’t involve anything that might throw. 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.

However there are also cases where move could throw.

One example is if you use certain kinds of allocators and you “move” from a container that uses a allocator in some area of memory to a container with allocation in some other area of memory. That “move” really involves copy, which means it might throw if allocations fail. If you don’t use custom allocators this does not apply to your application.

Containers with dynamically allocated sentinel

However there is another case that involves standard containers such as std::list , std::deque , std::map etc. even if custom allocators are not involved.

For example Microsoft’s std::list can throw in move constructors.

Array

This is due to a combination of design decissions that end up having consequences.

  • It uses a dynamically allocated sentinel: the dummy node with two pointers next and prev , but value. This has the advantage that it provides an end iterator that does not get invalidated in a variety of scenarios. E.g. the end iterator for std::vector gets invalidated on resizes, inserts etc.
  • It does not have “moved from” state that is different from an empty container. This is a dubious decision, but I believe it’s mandated by the standard and would be difficult to change. A much better idiom would have been to say “moved from objects can be destroyed or assigned to, but not usable otherwise”.
  • The way the move semantics is implemented in C++: the move constructor does not know if/how the “moved from” object will be used.

Therefore a vector of container with dynamically allocated sentinel, e.g. Microsoft’s std::vector<std::list<int>> , copies the values on a push_back resize, in order to maintain the strong guarantees, in face of the Microsoft’s std::list not having a noexcept move constructor.

It turns out that many other of Microsoft’s standard containers have the same issue std::map , std::unordered_map , std::deque etc.

g++ seems to kind of avoid this issue except for std::deque . To complicate further, std::vector<std::deque<int>> is fine, because of a special treatment.

However for both:

some_struct { std::list<int> m0; std::deque<int> m1; }; // would copy for resize of // std::vector<some_struct> // just as it did pre-C++11

NOTE: I used Microsoft vs g++ compilers as a oversimplification. More precisely, the behaviour depends on the standard library implementation, not on the compiler. For a survey of container noexcept behaviour see:

Howard E. Hinnant: Container Survey - 2015-06-27

Ville Voutilainen et al. N4055: Ruminations on (node-based) containers and noexcept - 2014-07-02

Testing the vector behaviour source code .

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Move Constructors and Move Assignment Operators (C++)

  • 9 contributors

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, MemoryBlock , which manages a memory buffer.

The following procedures describe how to write a move constructor and a move assignment operator for the example C++ class.

To create a move constructor for a C++ class

Define an empty constructor method that takes an rvalue reference to the class type as its parameter, as demonstrated in the following example:

In the move constructor, assign the class data members from the source object to the object that is being constructed:

Assign the data members of the source object to default values. This prevents the destructor from freeing resources (such as memory) multiple times:

To create a move assignment operator for a C++ class

Define an empty assignment operator that takes an rvalue reference to the class type as its parameter and returns a reference to the class type, as demonstrated in the following example:

In the move assignment operator, add a conditional statement that performs no operation if you try to assign the object to itself.

In the conditional statement, free any resources (such as memory) from the object that is being assigned to.

The following example frees the _data member from the object that is being assigned to:

Follow steps 2 and 3 in the first procedure to transfer the data members from the source object to the object that is being constructed:

Return a reference to the current object, as shown in the following example:

Example: Complete move constructor and assignment operator

The following example shows the complete move constructor and move assignment operator for the MemoryBlock class:

Example Use move semantics to improve performance

The following example shows how move semantics can improve the performance of your applications. The example adds two elements to a vector object and then inserts a new element between the two existing elements. The vector class uses move semantics to perform the insertion operation efficiently by moving the elements of the vector instead of copying them.

This example produces the following output:

Before Visual Studio 2010, this example produced the following output:

The version of this example that uses move semantics is more efficient than the version that does not use move semantics because it performs fewer copy, memory allocation, and memory deallocation operations.

Robust Programming

To prevent resource leaks, always free resources (such as memory, file handles, and sockets) in the move assignment operator.

To prevent the unrecoverable destruction of resources, properly handle self-assignment in the move assignment operator.

If you provide both a move constructor and a move assignment operator for your class, you can eliminate redundant code by writing the move constructor to call the move assignment operator. The following example shows a revised version of the move constructor that calls the move assignment operator:

The std::move function converts the lvalue other to an rvalue.

Rvalue Reference Declarator: && std::move

Was this page helpful?

Additional resources

  • <cassert> (assert.h)
  • <cctype> (ctype.h)
  • <cerrno> (errno.h)
  • C++11 <cfenv> (fenv.h)
  • <cfloat> (float.h)
  • C++11 <cinttypes> (inttypes.h)
  • <ciso646> (iso646.h)
  • <climits> (limits.h)
  • <clocale> (locale.h)
  • <cmath> (math.h)
  • <csetjmp> (setjmp.h)
  • <csignal> (signal.h)
  • <cstdarg> (stdarg.h)
  • C++11 <cstdbool> (stdbool.h)
  • <cstddef> (stddef.h)
  • C++11 <cstdint> (stdint.h)
  • <cstdio> (stdio.h)
  • <cstdlib> (stdlib.h)
  • <cstring> (string.h)
  • C++11 <ctgmath> (tgmath.h)
  • <ctime> (time.h)
  • C++11 <cuchar> (uchar.h)
  • <cwchar> (wchar.h)
  • <cwctype> (wctype.h)

Containers:

  • C++11 <array>
  • <deque>
  • C++11 <forward_list>
  • <list>
  • <map>
  • <queue>
  • <set>
  • <stack>
  • C++11 <unordered_map>
  • C++11 <unordered_set>
  • <vector>

Input/Output:

  • <fstream>
  • <iomanip>
  • <ios>
  • <iosfwd>
  • <iostream>
  • <istream>
  • <ostream>
  • <sstream>
  • <streambuf>

Multi-threading:

  • C++11 <atomic>
  • C++11 <condition_variable>
  • C++11 <future>
  • C++11 <mutex>
  • C++11 <thread>
  • <algorithm>
  • <bitset>
  • C++11 <chrono>
  • C++11 <codecvt>
  • <complex>
  • <exception>
  • <functional>
  • C++11 <initializer_list>
  • <iterator>
  • <limits>
  • <locale>
  • <memory>
  • <new>
  • <numeric>
  • C++11 <random>
  • C++11 <ratio>
  • C++11 <regex>
  • <stdexcept>
  • <string>
  • C++11 <system_error>
  • C++11 <tuple>
  • C++11 <type_traits>
  • C++11 <typeindex>
  • <typeinfo>
  • <utility>
  • <valarray>
  • vector<bool>
  • vector::~vector
  • vector::vector

member functions

  • vector::assign
  • vector::back
  • vector::begin
  • vector::capacity
  • C++11 vector::cbegin
  • C++11 vector::cend
  • vector::clear
  • C++11 vector::crbegin
  • C++11 vector::crend
  • C++11 vector::data
  • C++11 vector::emplace
  • C++11 vector::emplace_back
  • vector::empty
  • vector::end
  • vector::erase
  • vector::front
  • vector::get_allocator
  • vector::insert
  • vector::max_size
  • vector::operator[]
  • vector::operator=
  • vector::pop_back
  • vector::push_back
  • vector::rbegin
  • vector::rend
  • vector::reserve
  • vector::resize
  • C++11 vector::shrink_to_fit
  • vector::size
  • vector::swap

non-member overloads

  • relational operators (vector)
  • swap (vector)

std:: vector ::assign

range (1)
fill (2)
range (1)
fill (2)
initializer list (3)

Return value

main () { std::vector< > first; std::vector< > second; std::vector< > third; first.assign (7,100); std::vector< >::iterator it; it=first.begin()+1; second.assign (it,first.end()-1); myints[] = {1776,7,4}; third.assign (myints,myints+3); std::cout << << (first.size()) << ; std::cout << << (second.size()) << ; std::cout << << (third.size()) << ; 0; }

Iterator validity

Exception safety.

cppreference.com

Std::vector<t,allocator>:: vector.

(C++20)
(C++20)
(C++11)
(C++20)
(C++17)
(C++11)
(C++11)
Tables

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

Powered by MediaWiki

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.

  • memory-management

Jamal's user avatar

  • \$\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

Loki Astari's user avatar

  • \$\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?

vector assignment move

  • 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)?

Violet Giraffe's user avatar

  • 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.

devoured elysium's user avatar

  • 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 .

Open AI - Opting Out's user avatar

  • 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.

Cheers and hth. - Alf's user avatar

  • 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.

James Kanze's user avatar

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.

Symaxion's user avatar

  • 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.

FredericS's user avatar

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?

vector assignment move

IMAGES

  1. Vectors 2

    vector assignment move

  2. Vector Assign at Vectorified.com

    vector assignment move

  3. [Solved] Move Constructor, move vector between two

    vector assignment move

  4. C++ : Move Constructor, move vector between two objects using std::move

    vector assignment move

  5. Vectors Assignment AA HL

    vector assignment move

  6. // ADD: the "move constructor" Vector (Vector&& rhs)

    vector assignment move

VIDEO

  1. REACT _vector_

  2. Vector Painting Assignment

  3. Vector Table

  4. Fundamentals Pen Tool Vector Assignment

  5. 39 Vector Analysis Lab Assignment

  6. Vectors To Motion in 1D: Position

COMMENTS

  1. STL vector: Moving all elements of a vector

    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 ...

  2. What is std::move (), and when should it be used?

    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 ...

  3. Move assignment operator

    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 ...

  4. Moving elements from std::vector to another one

    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 ...

  5. Move Assignment Operator in C++ 11

    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.

  6. std::move

    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 ...

  7. std::move in Utility in C++

    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 ...

  8. 22.3

    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 ...

  9. How vector works

    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.

  10. std::vector<T,Allocator>::operator=

    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 ...

  11. 22.4

    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.

  12. vector

    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 ...

  13. Move Constructors and Move Assignment Operators (C++)

    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 ...

  14. vector

    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 ...

  15. std::vector<T,Allocator>::assign

    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 ...

  16. C++11 Vector with move semantics

    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 ...

  17. 16.5

    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;

  18. std::vector<T,Allocator>::vector

    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 ...

  19. Why std::move is required to invoke move assign operator of std::vector

    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.

  20. Vector with move constructor and move assignment operator

    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];

  21. Copying std::vector: prefer assignment or std::copy?

    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.