C++20 ввёл концепты — способ формально выразить требования к типам. В Ranges они используются повсеместно, поэтому важно понимать, что говорят сообщения об ошибках и почему один алгоритм принимает
vector, а другой требует что-то большее.// ❌ Не скомпилируется
std::list<int> lst = {3, 1, 2};
std::ranges::sort(lst);
// Ошибка: list не удовлетворяет концепту random_access_range
// ✅ vector удовлетворяет random_access_range
std::vector<int> vec = {3, 1, 2};
std::ranges::sort(vec);
// ✅ У list есть собственный метод сортировки
lst.sort();
🍋 Иерархия концептов
Концепты выстроены в цепочку наследования: каждый следующий добавляет требования к предыдущему.
sized_range и viewable_range — ортогональны иерархии, они не зависят от позиции в цепочке.range
└── input_range
└── forward_range
└── bidirectional_range
└── random_access_range
└── contiguous_range
‼️ Зачем нужен viewable_range?
Ещё есть viewable_range, он тоже не входит в иерархию. Нужен, так как не любой range можно безопасно обернуть во view. Если передать временный объект, итератор получит висячий указатель — объект уничтожается раньше, чем его успевают использовать. Концепт
viewable_range запрещает это на уровне компилятора.🍩 Проверка концептов в compile-time
Тут всё просто, нужно обернуть проверку в
static_assert и сразу, на этапе компиляции, получишь ошибку если что-то не так:static_assert(std::ranges::random_access_range<std::vector<int>>);
static_assert(!std::ranges::random_access_range<std::list<int>>);
static_assert(std::ranges::bidirectional_range<std::list<int>>);
🐸 Продолжение следует...
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#константная_правильность