Templates and generic programming
T.24
Используйте классы-теги или трейты для различения концептов, отличающихся только семантикой
Причина
Два концепта с одинаковым синтаксисом, но разной семантикой ведут к неоднозначности, если программист не разграничивает их явно.
Пример
template<typename I> // итератор, предоставляющий произвольный доступ
// Примечание: random_access_iterator определён в <iterator>
concept RA_iter = ...;
template<typename I> // итератор, предоставляющий произвольный доступ к непрерывным данным
// Примечание: contiguous_iterator определён в <iterator>
concept Contiguous_iter =
RA_iter<I> && is_contiguous_v<I>; // используем трейт is_contiguous
Программист (в библиотеке) должен соответствующим образом определить is_contiguous (трейт).
Обёртывание класса-тега в концепт приводит к более простому выражению этой идеи:
template<typename I> concept Contiguous = is_contiguous_v<I>;
template<typename I>
concept Contiguous_iter = RA_iter<I> && Contiguous<I>;
Программист (в библиотеке) должен соответствующим образом определить is_contiguous (трейт).
Примечание
Трейты могут быть классами-трейтами или трейтами типов. Они могут быть определены пользователем или предоставлены стандартной библиотекой. Предпочитайте трейты стандартной библиотеки.
Контроль
- Компилятор помечает неоднозначное использование одинаковых концептов.
- Помечать определение одинаковых концептов.