C++11
The release that split C++ into "old" and "modern." Move semantics eliminates unnecessary copies. Lambdas replace manual functors. auto reduces verbosity. Smart pointers replace raw new/delete. std::thread brings concurrency to the standard. Every C++ programmer needs to know these features cold.
Core Language
Transfer ownership instead of copying. Eliminates unnecessary deep copies for temporaries and enables efficient container operations.
#include <vector>
#include <string>
std::string make_greeting(std::string name) {
return "Hello, " + std::move(name) + "!";
// name is moved-from, not copied
}
// Move constructor — O(1) instead of O(n)
std::vector<int> a{1, 2, 3, 4, 5};
std::vector<int> b = std::move(a); // a is now empty, b owns the data
// Forwarding references (perfect forwarding)
template<typename T>
void wrapper(T&& arg) {
target(std::forward<T>(arg)); // preserves lvalue/rvalue category
}Anonymous function objects with captures. Replace manual functor classes for algorithms, callbacks, and local logic.
#include <algorithm>
#include <vector>
std::vector<int> v{3, 1, 4, 1, 5, 9, 2, 6};
// Lambda as algorithm predicate
std::sort(v.begin(), v.end(),
[](int a, int b) { return a > b; }); // descending
// Capture by value and reference
int threshold = 3;
auto count = std::count_if(v.begin(), v.end(),
[threshold](int x) { return x > threshold; });
// Capture all by reference — mutable
int sum = 0;
std::for_each(v.begin(), v.end(),
[&sum](int x) { sum += x; });Let the compiler deduce variable types from initializers. Avoids typing long iterator types, enables generic code, and prevents silent conversions.
#include <map>
#include <vector>
// Iterator type — no more verbosity
std::map<std::string, std::vector<int>> data;
auto it = data.begin(); // was: std::map<...>::iterator it
// Return type deduction for trailing return
auto add(int a, int b) -> int { return a + b; }
// Range-based for with auto
for (const auto& [key, values] : data) {
for (auto v : values) { /* ... */ }
}Iterate any container, array, or range without index arithmetic. Works with anything that has begin()/end().
#include <vector>
#include <string>
std::vector<int> v{1, 2, 3, 4, 5};
// By value (copy)
for (int x : v) { /* x is a copy */ }
// By const ref — preferred for non-trivial types
for (const auto& x : v) { /* no copy */ }
// By ref — for mutation
for (auto& x : v) { x *= 2; }
// C array
int arr[] = {1, 2, 3};
for (int n : arr) { /* works */ }Templates that accept any number of type parameters. Foundation for std::tuple, std::make_unique, std::bind, and perfect-forwarding wrappers.
// Accept any number of args of any type
template<typename... Args>
void print_all(Args&&... args) {
(std::cout << ... << args); // C++17 fold; in C++11: recursion
}
// Recursive variadic (C++11 style)
template<typename T>
void print(T first) { std::cout << first << '\n'; }
template<typename T, typename... Rest>
void print(T first, Rest... rest) {
std::cout << first << ' ';
print(rest...); // recurse with tail
}
print(1, 2.0, "three"); // "1 2.0 three"Functions and variables evaluated at compile time. Eliminates macros for constants; enables compile-time computation without template metaprogramming.
constexpr int factorial(int n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}
constexpr int f5 = factorial(5); // computed at compile time = 120
// constexpr variable
constexpr double PI = 3.141592653589793;
// Use in template arguments (requires compile-time value)
std::array<int, factorial(5)> arr; // std::array<int, 120>Library
std::unique_ptr and std::shared_ptr replace raw new/delete. Automatic lifetime management via RAII. std::weak_ptr breaks cycles.
#include <memory>
// unique_ptr — sole ownership, no overhead
auto p = std::make_unique<Widget>(arg1, arg2);
// auto q = p; // ERROR: can't copy
auto q = std::move(p); // transfer ownership
// shared_ptr — shared ownership, reference counted
auto s1 = std::make_shared<Node>();
auto s2 = s1; // both own the same Node
// Node destroyed when both s1 and s2 go out of scope
// weak_ptr — non-owning observer, breaks cycles
std::weak_ptr<Node> weak = s1;
if (auto locked = weak.lock()) { // check still alive
locked->use();
}First-class threading in the standard library. std::thread, std::mutex, std::atomic, std::condition_variable — portable concurrency.
#include <thread>
#include <mutex>
#include <atomic>
std::mutex mtx;
std::atomic<int> counter{0};
void worker() {
for (int i = 0; i < 1000; ++i) {
++counter; // atomic — no mutex needed
std::lock_guard<std::mutex> lock(mtx);
// critical section
}
}
std::thread t1(worker), t2(worker);
t1.join();
t2.join();
// counter == 2000, no data raceFixed-size heterogeneous collection. Works with structured bindings (C++17), std::tie, std::get, and std::apply.
#include <tuple>
auto make_record(std::string name, int age, double score) {
return std::make_tuple(std::move(name), age, score);
}
auto record = make_record("Alice", 30, 95.5);
// Get by index
std::string name = std::get<0>(record);
int age = std::get<1>(record);
// std::tie unpacks into existing variables
std::string n; int a; double s;
std::tie(n, a, s) = record;Type-erased callable wrapper. Store lambdas, function pointers, and member functions uniformly. std::bind for partial application.
#include <functional>
// Store any callable
std::function<int(int, int)> op;
op = [](int a, int b) { return a + b; };
op = std::plus<int>{}; // standard functor
// Partial application with bind
using namespace std::placeholders;
auto add5 = std::bind(std::plus<int>{}, _1, 5);
add5(3); // 8
add5(10); // 15Hash-based containers with O(1) average lookup. Use when you don't need ordering and performance matters more than worst-case guarantees.
#include <unordered_map>
#include <unordered_set>
std::unordered_map<std::string, int> word_count;
word_count["hello"] = 1;
word_count["world"] = 2;
word_count["hello"]++; // O(1) average lookup
// Custom hash for user types
struct Point { int x, y; };
struct PointHash {
std::size_t operator()(const Point& p) const {
return std::hash<int>{}(p.x) ^ (std::hash<int>{}(p.y) << 1);
}
};
std::unordered_set<Point, PointHash> points;