Используйте шаблоны для повышения уровня абстракции кода
Причина
Обобщённость. Повторное использование. Эффективность. Способствует согласованному определению пользовательских типов.
Пример (плохой)
Концептуально следующие требования ошибочны, потому что от T нам нужно больше, чем просто низкоуровневые концепты «можно инкрементировать» или «можно складывать»:
template<typename T>
requires Incrementable<T>
T sum1(vector<T>& v, T s)
{
for (auto x : v) s += x;
return s;
}
template<typename T>
requires Simple_number<T>
T sum2(vector<T>& v, T s)
{
for (auto x : v) s = s + x;
return s;
}
Предполагая, что Incrementable не поддерживает +, а Simple_number не поддерживает +=, мы чрезмерно ограничиваем реализаторов sum1 и sum2. И при этом упускаем возможность для обобщения.
Пример
template<typename T>
requires Arithmetic<T>
T sum(vector<T>& v, T s)
{
for (auto x : v) s += x;
return s;
}
Предполагая, что Arithmetic требует как +, так и +=, мы ограничиваем пользователя sum необходимостью предоставить полноценный арифметический тип. Это не минимальное требование, но оно предоставляет реализаторам алгоритмов необходимую свободу и гарантирует, что любой тип Arithmetic можно использовать в широком спектре алгоритмов.
Для большей обобщённости и возможности повторного использования можно также применять более общий концепт Container или Range вместо привязки только к одному контейнеру vector.
Примечание
Если мы определяем шаблон так, чтобы он требовал ровно те операции, которые нужны для одной конкретной реализации одного алгоритма (например, требуем только += вместо = и +), мы чрезмерно ограничиваем сопровождающих. Мы стремимся минимизировать требования к аргументам шаблона, но абсолютно минимальные требования конкретной реализации редко образуют содержательный концепт.
Примечание
Шаблоны могут выражать практически что угодно (они тьюринг-полны), но цель обобщённого программирования (выраженного через шаблоны) — эффективно обобщать операции/алгоритмы на множестве типов со схожими семантическими свойствами.
Контроль
- Помечать алгоритмы со «слишком простыми» требованиями, такими как прямое использование конкретных операторов без концепта.
- Не помечать определения самих «слишком простых» концептов: они могут быть просто строительными блоками для более полезных концептов.