Dynamic Arrays using std::vector

Using Vector with Move-Only Types

Can I use std::vector with move-only types like std::unique_ptr?

Abstract art representing computer programming

Yes, you can use std::vector with move-only types like std::unique_ptr. However, there are some important considerations and best practices to keep in mind.

Basic Usage

Here's a simple example of using std::vector with std::unique_ptr:

#include <iostream>
#include <vector>
#include <memory>

class Resource {
public:
  Resource(int id) : id(id){
    std::cout << "Resource " << id <<
      " created\n";
  }

  ~Resource(){
    std::cout << "Resource " << id <<
      " destroyed\n";
  }

  int getId() const{ return id; }

private:
  int id;
};

int main(){
  std::vector<std::unique_ptr<Resource>>
    resources;

  // Adding elements
  resources.push_back(
    std::make_unique<Resource>(1)); 
  resources.emplace_back(
    std::make_unique<Resource>(
      2)); // Accessing elements
  for (const auto& resource : resources) {
    std::cout << "Resource ID: "
      << resource->getId() << '\n';
  }

  // Vector will automatically delete the 
  // Resources when it goes out of scope
}
Resource 1 created
Resource 2 created
Resource ID: 1
Resource ID: 2
Resource 2 destroyed
Resource 1 destroyed

Considerations

  1. Use std::move() with the emplace_back() or push_back() methods: Since std::unique_ptr is move-only, you need to use emplace_back() or push_back() with std::move() to add elements.
  2. Avoid copy operations: std::vector may need to reallocate and move its elements when it grows. Ensure your move-only types have efficient move constructors and move assignment operators.
  3. Be cautious with reallocation: When std::vector reallocates, it moves all its elements. This is fine for std::unique_ptr, but could be problematic for other move-only types that have side effects when moved.
  4. Be careful with algorithms: Some standard algorithms may not work with move-only types. Always check the requirements of algorithms you plan to use.

Additionally, to minimize reallocations, consider using reserve() if you know how many elements you'll be adding:

std::vector<std::unique_ptr<Resource>> resources;

// Prepare space for 10 elements
resources.reserve(10);

Example with Custom Move-Only Type

Here's an example with a custom move-only type:

#include <iostream>
#include <vector>
#include <utility>

class MoveOnlyType {
public:
  MoveOnlyType(int value) : value(value){
    std::cout << "MoveOnlyType " << value <<
      " created\n";
  }

  MoveOnlyType(const MoveOnlyType&) = delete;
  MoveOnlyType& operator=(const MoveOnlyType&)
  = delete;

  MoveOnlyType(MoveOnlyType&& other) noexcept
    : value(other.value){
    std::cout << "MoveOnlyType " << value <<
      " moved\n";
    other.value = 0;
  }

  MoveOnlyType& operator=(
    MoveOnlyType&& other) noexcept{
    if (this != &other) {
      value = other.value;
      other.value = 0;
      std::cout << "MoveOnlyType " << value
        << " move assigned\n";
    }
    return *this;
  }

  ~MoveOnlyType(){
    std::cout << "MoveOnlyType " << value <<
      " destroyed\n";
  }

  int getValue() const{ return value; }

private:
  int value;
};

int main(){
  std::vector<MoveOnlyType> vec;
  vec.reserve(3);
  // Avoid reallocation for this example

  vec.push_back(MoveOnlyType(1));
  vec.emplace_back(2);
  vec.push_back(std::move(MoveOnlyType(3)));

  for (const auto& item : vec) {
    std::cout << "Value: " << item.getValue() <<
      '\n';
  }
}
MoveOnlyType 1 created
MoveOnlyType 1 moved
MoveOnlyType 0 destroyed
MoveOnlyType 2 created
MoveOnlyType 3 created
MoveOnlyType 3 moved
MoveOnlyType 0 destroyed
Value: 1
Value: 2
Value: 3
MoveOnlyType 1 destroyed
MoveOnlyType 2 destroyed
MoveOnlyType 3 destroyed

This example demonstrates creating, moving, and destroying move-only objects within a std::vector. Understanding these concepts is crucial when working with move-only types in containers like std::vector.

Answers to questions are automatically generated and may not have been reviewed.

3D art showing a progammer setting up a development environment
Part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, unlimited access

This course includes:

  • 57 Lessons
  • Over 200 Quiz Questions
  • 95% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved