1. Обзор стандартов

1.1. Возможности языка на примере стандарта C++98

1.2. Инкапсуляция, наследование, полиморфизм

1.3. Перегрузка

1.4. SFINAE

#include <iostream>
#include <list>
#include <tuple>
#include <vector>

struct sfinae
{
private:
    template<class U>
    constexpr static bool f(typename U::value_type*)
    {
        return true;
    }

    template<class U>
    constexpr static bool f(...)
    {
        return false;
    }

public:
    template<class T>
    constexpr static bool is_container = f<T>(nullptr);
};

int main()
{
    std::cout << std::boolalpha;

    auto types = std::make_tuple(std::vector<int>{}, std::list<double>{}, int{}, static_cast<const char*>(nullptr));
    std::apply([](auto... xs) {
        ((std::cout << "Is a container? " << sfinae::is_container<decltype(xs)> << "\n"), ...);
    }, types);
}
Output
Is a container? true
Is a container? true
Is a container? false
Is a container? false

1.5. Шаблоны

2. Обзор стандарта C++03

2.1. Нововведения

3. Обзор стандарта C++11

3.1. Новые возможности языка

3.2. Новые возможности языка (продолжение)

3.3. Расширение STL

4. Обзор стандарта C++14

4.1. Новые возможности языка

4.2. Нововведения в STL

5. Обзор стандарта C++17

5.1. Новые возможности языка

5.2. Нововведения в STL

6. Обзор современных особенностей языка C++

6.1. О using директиве

6.2. О rvalue

6.3. О конструкторах

class A {
public:
    A(); // default constructor
    A(const A&); // copy constructor
    A(A&&); // move constructor
    A& operator=(const A&); // copy assignment
    A& operator=(A&&); // move assignment
    ~A(); // destructor
}

6.4. О шаблонах

6.5. Распаковка кортежа в аргументы

#include <iostream>
#include <tuple>
#include <utility>

template<class Stream, class Tuple, size_t... Is>
Stream& func_impl(Stream& os, const Tuple& t, std::index_sequence<Is...>)
{
    return (os << ... << std::get<Is>(t));
}

/*template<class Stream, class... Ts>
Stream& func1(Stream& os, const std::tuple<Ts...>& t)
{
    func_impl(os, t, std::index_sequence_for<Ts...>{});
}*/

template<class Stream, class Tuple>
Stream& func2(Stream& os, const Tuple& t)
{
    return func_impl(os, t, std::make_index_sequence<std::tuple_size_v<Tuple>>{});
}

template<class... Ts>
std::ostream& operator<<(std::ostream& os, const std::tuple<Ts...>& t)
{
    // return std::apply([&os](const auto&... xs) -> decltype(auto) { return (os << ... << xs); }, t);
    return func2(os, t);
}

int main()
{
    std::cout << std::tuple{1, ' ', 2.3, ' ', "lala"} << "\n";
}
Output
1 2.3 lala

6.6. Операции над шаблонными пакетами

template <typename... bases>
struct X : bases... {
    using X::bases::g...;
};
X<B, D> x;

Свёртки (наличие скобок важно)

template<typename T, typename... Args>
void push_back_vec(std::vector<T>& v, Args&&... args)
{
    (v.push_back(std::forward<Args>(args)), ...);
}

6.7. О лямбда-выражениях

auto f = [a = 77, &b](auto x) mutable -> int { b = x - 78; return a++; }

7. Следующие стандарты

7.1. Концепты и ограничители

// концепт: как описывать
template<typename T>
concept EqualityComparable = requires(T a, T b)
{
    { a == b } -> bool;
};

// ограничитель: как применять
template<EqualityComparable T> void f(T&&);

// или так применять
template<class T> requires EqualityComparable<T> void f(T&&);

7.2. Новое в STL