Избегайте соседних параметров, которые могут быть вызваны с теми же аргументами в любом порядке с разным смыслом
Причина
Соседние аргументы одного типа легко перепутать местами по ошибке.
Пример (плохой)
Рассмотрим:
void copy_n(T* p, T* q, int n); // копировать из [p:p + n) в [q:q + n)
Это неприятный вариант интерфейса в стиле K&R C. Легко перепутать аргументы «куда» и «откуда».
Используйте const для аргумента «откуда»:
void copy_n(const T* p, T* q, int n); // копировать из [p:p + n) в [q:q + n)
Исключение
Если порядок параметров не важен, проблемы нет:
int max(int a, int b);
Альтернатива
Не передавайте массивы как указатели, передавайте объект, представляющий диапазон (например, span):
void copy_n(span<const T> p, span<T> q); // копировать из p в q
Альтернатива
Определите struct в качестве типа параметра и назовите поля соответствующим образом:
struct SystemParams {
string config_file;
string output_path;
seconds timeout;
};
void initialize(SystemParams p);
Это, как правило, делает вызовы понятными для будущих читателей, поскольку параметры часто заполняются по именам в точке вызова.
Примечание
Только проектировщик интерфейса может адекватно устранить источник нарушений этого руководящего принципа.
Стратегия контроля
(Простой) Предупреждать, если два последовательных параметра имеют одинаковый тип.
Мы всё ещё ищем менее простой способ применения.