Искусственная типизация однородных параметров в C++

Допустим есть вот такой класс:

class Date {
 public:
  Date(int year, int month, int day) {
    ...
  }
};

К сожалению, не весь мир пользуется логичной нотацией Год/Месяц/День или День/Месяц/Год. Иногда люди пишут Месяц/День/Год. Хотя и первые два легко перепутать. Вот к чему я веду: где-то в далеком от описания класса коде кто-то пишет:

Date d(2009, 4, 5);

Что он этим хотел сказать? 4-е Мая или 5-е Апреля? Сложно быть уверенным, что пользователь такого класса когда-нибудь не перепутает порядок аргументов.

Можно улучшить дизайн? Да.

Например, так:

class Year {
 public:
  explicit Year(int year) : year_(year) {}
  operator int() const { return year_; }
 private:
  int year_;
};

И аналогично:

class Month { ... };
class Day { ... };

Интерфейс самого класса Date может быть таким:

class Date {
 public:
   Date(Year year, Month month, Day day);
   Date(Month month, Day day, Year year);
   Date(Day day, Month month, Year year);
}

И использовать класс надо так:

Date d(Year(2010), Month(4), Day(5));

или

Date d(Month(4), Day(5), Year(2010));

Результат будет всегда предсказуем и виден в вызывающем коде. Тут все inline’овое, так что эти три “лишние” класса никакого замедления не дадут.

Согласен, писанины немного больше, но зато полная гарантия от опечаток и, как следствие, глупых, но коварных ошибок.

Возражения есть?


Оригинальный пост | Disclaimer

Комментарии