Modern C++ Features (C++11 and Beyond)
Explore modern C++ features including auto, lambdas, ranges, and coroutines. Learn how C++11/14/17/20 transformed the language.
Best viewed on desktop for optimal interactive experience
Modern C++: Evolution of the Language
Modern C++ (C++11 and later) introduced revolutionary features that make the language safer, more expressive, and easier to use. These features transformed C++ from a low-level systems language into a powerful, high-level programming language while maintaining its performance characteristics.
Major C++ Standards
- C++11: The foundation of modern C++
- C++14: Refinements and small additions
- C++17: Parallel algorithms and more
- C++20: Ranges, coroutines, concepts, and modules
Modern C++ Evolution
C++11
- • auto
- • lambdas
- • move semantics
- • smart pointers
C++14
- • generic lambdas
- • variable templates
- • make_unique
C++17
- • structured bindings
- • optional
- • parallel algorithms
C++20
- • concepts
- • ranges
- • coroutines
- • modules
Interactive Feature Explorer
Auto & Type Deduction
// Basic auto usage
auto x = 42; // int
auto y = 3.14; // double
auto str = "hello"; // const char*
auto vec = std::vector<int>{}; // std::vector<int>
// More complex cases
auto lambda = [](int x) { return x * 2; };
auto it = vec.begin();
auto pair = std::make_pair(1, "hello");
// AAA (Almost Always Auto)
auto config = Config{};
auto mutex = std::mutex{};
auto lock = std::lock_guard<std::mutex>{mutex};
Auto Guidelines:
- • Use auto for complex types and iterators
- • Be explicit when type matters for readability
- • Watch out for reference/pointer deduction
- • Consider AAA (Almost Always Auto) for consistency
Adoption Strategy
Gradual Migration Path
- 1Start with
auto
and range-based for loops - 2Replace raw pointers with smart pointers
- 3Use lambdas for small functions and callbacks
- 4Adopt move semantics for performance-critical code
- 5Explore ranges and coroutines for new projects
Key Benefits
- Safer code: Better type safety and resource management
- More expressive: Code that clearly expresses intent
- Better performance: Zero-cost abstractions and move semantics
- Easier maintenance: Less boilerplate and cleaner APIs
Auto: Type Deduction
Before C++11
std::vector<std::string>::iterator it = vec.begin(); std::map<std::string, int>::const_iterator map_it = myMap.find(key);
With Auto
auto it = vec.begin(); auto map_it = myMap.find(key); auto lambda = [](int x) { return x * 2; };
Auto Guidelines
- Use for complex types and iterators
- Be explicit when type clarity matters
- Watch out for reference/pointer deduction
- Follow AAA (Almost Always Auto) when appropriate
Lambda Expressions
Basic Syntax
[capture](parameters) -> return_type { body }
Capture Modes
[=]
: Capture by value (copy)[&]
: Capture by reference[x]
: Capture specific variable by value[&x]
: Capture specific variable by reference[=, &x]
: Mixed capture modes
Lambda Evolution
- C++11: Basic lambdas
- C++14: Generic lambdas with auto parameters
- C++17: Constexpr lambdas
- C++20: Template parameter lists in lambdas
Ranges (C++20)
Traditional Approach
std::vector<int> numbers{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; std::vector<int> result; for (int n : numbers) { if (n % 2 == 0) { result.push_back(n * n); } }
Ranges Approach
auto result = numbers | std::views::filter([](int n) { return n % 2 == 0; }) | std::views::transform([](int n) { return n * n; });
Ranges Benefits
- Lazy evaluation: No intermediate containers
- Composable: Chain operations naturally
- Efficient: Minimal memory allocations
- Readable: Clear expression of intent
Move Semantics (C++11)
Rvalue References
class Widget { std::vector<int> data; public: // Move constructor Widget(Widget&& other) noexcept : data(std::move(other.data)) {} // Move assignment Widget& operator=(Widget&& other) noexcept { if (this != &other) { data = std::move(other.data); } return *this; } };
Perfect Forwarding
template<typename T> void wrapper(T&& arg) { function(std::forward<T>(arg)); }
Coroutines (C++20)
Generator Pattern
Generator<int> fibonacci() { int a = 0, b = 1; while (true) { co_yield a; auto next = a + b; a = b; b = next; } } // Usage auto fib = fibonacci(); for (int i = 0; i < 10 && fib.next(); ++i) { std::cout << fib.value() << " "; }
Other Important Features
C++11
- Range-based for loops
- Nullptr
- Uniform initialization
- Smart pointers
- Thread support library
C++14
- Variable templates
- Generic lambdas
- Make functions for smart pointers
C++17
- Structured bindings
- Optional and variant types
- Parallel algorithms
- Filesystem library
C++20
- Concepts
- Modules
- Calendar and timezone library
- Three-way comparison operator
Adoption Strategy
- Start with auto and range-based for
- Replace raw pointers with smart pointers
- Use lambdas for small functions
- Adopt move semantics gradually
- Explore ranges and coroutines for new projects
Modern C++ provides the tools to write safer, more expressive code while maintaining the performance that makes C++ attractive for system programming.