Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🔴 Advanced  ·  Lesson 62

Modern C++ Features (C++11 to C++20)

In this lesson: Key modern C++ features — auto, range-for, lambdas, smart pointers, constexpr, structured bindings — with code. In Hindi & English.

What does "modern C++" mean?

C++ was standardised in 1998. For thirteen years it barely changed. Then C++11 arrived with so many improvements that people started calling it "modern C++". New standards now come every three years:

StandardYearHeadline features
C++112011auto, lambdas, smart pointers, move semantics, nullptr, range-based for, constexpr, threads
C++142014Generic lambdas, make_unique, return type deduction, binary literals
C++172017Structured bindings, std::optional, if with initialiser, string_view, inline variables
C++202020Concepts, ranges, std::format, modules, coroutines, <=> operator
C++232023std::print, std::expected, more ranges

This lesson shows the features you will use every day, each as *old way* vs *modern way*. Compile the examples with g++ -std=c++17 (or newer).

auto — let the compiler deduce the type

C++
std::map<std::string, std::vector<int>> marks;

// old
std::map<std::string, std::vector<int>>::iterator it = marks.begin();
// modern
auto it2 = marks.begin();

The type is still fixed at compile time. Use auto when the type is obvious or very long; write the type when it helps the reader.

Range-based for loop

C++
std::vector<int> v = {78, 91, 66};
// old
for (size_t i = 0; i < v.size(); i++) std::cout << v[i] << " ";
// modern
for (int m : v) std::cout << m << " ";          // copy
for (int& m : v) m += 5;                        // modify in place
for (const auto& m : v) std::cout << m << " ";  // read big objects without copying

nullptr instead of NULL

C++
int* p = nullptr;      // modern: a real null-pointer value with its own type
// int* q = NULL;      // old: really just 0, can confuse overload resolution

Uniform (brace) initialisation

C++
int count{};                          // 0
std::vector<int> v{1, 2, 3};
struct Point { int x, y; };
Point p{3, 4};
int narrow{3.7};                      // error: braces stop narrowing conversions

Smart pointers

C++
#include <memory>
// old
Student* s = new Student("Aman");
delete s;                             // easy to forget
// modern
auto s2 = std::make_unique<Student>("Aman");   // deleted automatically
auto s3 = std::make_shared<Student>("Priya");  // shared ownership, reference counted

See smart pointers.

Lambdas

C++
std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });

See lambda expressions.

Move semantics

Copying a vector of a million elements is expensive. Moving just hands over its internal buffer.

C++
#include <iostream>
#include <vector>
#include <utility>

int main() {
    std::vector<int> a(1000000, 7);
    std::vector<int> b = std::move(a);   // no element copied; a is left empty
    std::cout << "a: " << a.size() << ", b: " << b.size() << "\n";
    return 0;
}
a: 0, b: 1000000

Returning a local vector from a function is automatically moved (or the copy is elided entirely), so return result; is cheap.

constexpr — computed at compile time

C++
constexpr int factorial(int n) { return n <= 1 ? 1 : n * factorial(n - 1); }
constexpr int f5 = factorial(5);      // 120, calculated by the compiler
int table[factorial(4)];              // array of 24 ints

C++17 favourites

C++
#include <iostream>
#include <map>
#include <optional>
#include <string>

std::optional<int> findMarks(const std::map<std::string, int>& m, const std::string& name) {
    auto it = m.find(name);
    if (it == m.end()) return std::nullopt;    // "no value"
    return it->second;
}

int main() {
    std::map<std::string, int> marks{{"Aman", 78}, {"Priya", 91}};

    for (const auto& [name, score] : marks)             // structured bindings
        std::cout << name << " = " << score << "\n";

    if (auto r = findMarks(marks, "Ravi"); r.has_value())   // if with initialiser
        std::cout << "Ravi = " << *r << "\n";
    else
        std::cout << "Ravi not found\n";

    std::cout << "Priya = " << findMarks(marks, "Priya").value_or(0) << "\n";
    return 0;
}
Aman = 78 Priya = 91 Ravi not found Priya = 91
  • Structured bindings unpack pairs, tuples and structs: auto [x, y] = point;
  • **std::optional<T>** holds either a T or nothing — clearer than returning -1 for "not found".
  • **if (init; condition)** keeps a helper variable inside the if.
  • **std::string_view** is a cheap, read-only view of a string (no copy).

A taste of C++20

  • **std::format** — Python-style formatting: std::format("{} scored {}", name, marks).
  • Ranges — std::ranges::sort(v); instead of passing begin() and end().
  • Concepts — constrain templates: template<std::integral T> T gcd(T a, T b);
  • Three-way comparison <=> — one operator generates <, <=, >, >=.
  • **std::erase_if(v, pred)** — remove matching elements in one call.

Support for C++20 is good in GCC 11+, Clang 14+ and recent MSVC; compile with -std=c++20.

Old style vs modern style

TaskOld C++Modern C++
Dynamic arrayint* a = new int[n]; ... delete[] a;std::vector<int> a(n);
Owning pointerT* p = new T; ... delete p;auto p = std::make_unique<T>();
Null pointerNULL or 0nullptr
Loop over containerindex or iterator looprange-based for
Comparator for sortseparate named functionlambda
Constants#define MAX 100constexpr int MAX = 100;
"Maybe a value"special value like -1std::optional<int>

Common mistakes

  • Using Turbo C++ or -std=c++98 and wondering why auto/lambdas fail — set -std=c++17 in your IDE.
  • auto with braces: auto x{5}; is int, but auto y = {5}; is std::initializer_list<int>.
  • Using a variable after std::move as if it still had its old value.
  • Taking for (auto m : bigObjects) (copies) when const auto& was meant.
🏋️ Practice

Rewrite an old program of yours in modern style: replace new[]/delete[] with vector, NULL with nullptr, index loops with range-based for, #define with constexpr, and a "return -1 if not found" function with std::optional.

Summary

  • Modern C++ = C++11 and later; use at least -std=c++17.
  • Everyday features: auto, range-for, nullptr, brace init, smart pointers, lambdas.
  • Move semantics make passing and returning big objects cheap.
  • C++17 adds structured bindings, optional, if-init; C++20 adds format, ranges, concepts.
  • Modern style means fewer raw pointers and manual deletes.

Related: smart pointers, lambda, templates, C++ best practices.

Frequently Asked Questions

What is modern C++?
"Modern C++" usually means C++11 and later standards (C++14, C++17, C++20, C++23). C++11 was a major update that added auto, lambdas, smart pointers, move semantics, nullptr, range-based for and more, changing how everyday C++ code is written.
Which C++ version should a student use?
Use at least C++17; it is fully supported by current GCC, Clang and MSVC and is the default in recent GCC versions. Compile with -std=c++17 (or -std=c++20) if your compiler or IDE uses an older default. Turbo C++ does not support modern C++ at all.
What does auto do in C++?
Since C++11, auto tells the compiler to deduce a variable's type from its initialiser, e.g. auto x = 3.5; makes x a double, and auto it = v.begin(); avoids writing a long iterator type. The type is still fixed at compile time — C++ does not become dynamically typed.
What is move semantics in C++?
Move semantics (C++11) let an object transfer its resources, like a large buffer, to another object instead of copying them. std::move(x) marks x as movable. It makes returning and passing large objects such as std::vector and std::string much cheaper.
← Back to C++ Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.
Next topicSorting and Searching in C++ Your progress: 62 / 81 (77%) · Lesson 63 / 81 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free