Modern C++ Concepts | auto, Range-based for, Smart Pointers, Move Semantics, Rvalue References, std::move


This complete tutorial on Modern C++ Concepts explains auto keyword, range-based for loops, smart pointers, move semantics, rvalue references, and std::move. It helps learners write clean, efficient, and modern C++ code following best practices and memory safety principles.

Modern C++ Concepts – Complete Tutorial

1. auto Keyword

auto allows the compiler to deduce variable type automatically.

Example:


auto x = 10; // int
auto y = 3.14; // double
auto str = "Hello"; // const char*

Benefits:

  1. Reduces verbosity
  2. Useful with iterators and templates

2. Range-based For Loop

Simpler looping over containers or arrays.

Example:


#include <vector>
#include <iostream>
using namespace std;

int main() {
vector<int> v = {1,2,3,4,5};
for(auto n : v) cout << n << " "; // 1 2 3 4 5
}

Notes:

  1. Can use reference (auto&) to modify elements
  2. Works with arrays, vectors, maps, and sets

3. Smart Pointers

Smart pointers manage memory automatically and prevent leaks.

Types:

  1. unique_ptr – single ownership
  2. shared_ptr – shared ownership
  3. weak_ptr – avoids cyclic reference

Example – unique_ptr:


#include <memory>
#include <iostream>
using namespace std;

int main() {
unique_ptr<int> ptr = make_unique<int>(10);
cout << *ptr << endl;
}

Best Practices:

  1. Prefer unique_ptr unless shared ownership is needed
  2. Avoid raw new/delete

4. Move Semantics

Move semantics transfers resources from one object to another instead of copying.

Example:


#include <iostream>
#include <vector>
using namespace std;

vector<int> createVector() {
vector<int> v = {1,2,3};
return v; // moves instead of copying
}

int main() {
vector<int> v2 = createVector();
}

Benefits:

  1. Improves performance
  2. Avoids unnecessary copies

5. Rvalue References

Rvalue references (T&&) are used to identify temporary objects for moving.

Example:


void printVector(vector<int>&& v) {
for(int i : v) cout << i << " ";
}

int main() {
printVector(vector<int>{1,2,3});
}

Use Cases:

  1. Move constructors
  2. Move assignment operators
  3. Perfect forwarding

6. std::move

std::move casts an object to an rvalue reference, enabling move semantics.

Example:


#include <iostream>
#include <vector>
#include <utility>
using namespace std;

int main() {
vector<int> v1 = {1,2,3};
vector<int> v2 = std::move(v1); // v1’s data moved to v2
}

Notes:

  1. After move, v1 becomes empty but valid
  2. Useful for efficient resource transfer

Best Practices

  1. Use auto for cleaner code and iterators
  2. Use range-based for loops for readability
  3. Prefer smart pointers over raw pointers
  4. Implement move constructors and assignment operators for classes with dynamic resources
  5. Use std::move carefully to avoid using moved-from objects

Common Mistakes

  1. Using std::move on objects needed later
  2. Mixing raw pointers and smart pointers improperly
  3. Forgetting auto& in range-based loops when modifying elements
  4. Overusing shared_ptr unnecessarily (prefer unique_ptr)

Summary

In this chapter, you learned Modern C++ Concepts, including:

  1. auto keyword and type deduction
  2. Range-based for loops
  3. Smart pointers (unique_ptr, shared_ptr)
  4. Move semantics, rvalue references, and std::move

These concepts enhance code readability, performance, and safety, and are essential for modern C++ programming.