Недавно довелось столкнутся с задачкой, в которой пользователь должен определить тип с перечнем свойств. Что-то вроде traits из нашего проекта RESTinio. При этом внутри такого типа обязательно должна быть константа high_watermark типа std::size_t. Например:
struct my_traits { ... // Какие-то определения типов. // Максимальный размер при достижении которого нужно провести чистку данных. static constexpr std::size_t high_watermark = 64 * 1024 * 1024; }; |
А кроме этого может быть определена и вторая константа, low_watermark. Т.е. класс свойств может выглядеть и так:
struct my_traits { ... // Какие-то определения типов. // Максимальный размер при достижении которого нужно провести чистку данных. static constexpr std::size_t high_watermark = 64 * 1024 * 1024; // Размер при достижении которого чистку данных следует остановить. static constexpr std::size_t low_watermark = 16 * 1024 * 1024; }; |
При использовании таких типов свойств нужно было как-то понять, есть ли в свойствах константа low_watermark. Если есть, то нужно было использовать именно ее значение. А если нет, то оставалось высчитывать нижний порог из high_watermark.
Попробовал применить для этой цели концепты, благо в проекте C++20. Получилось так, как показано под катом.
Это лучшее, что удалось придумать. К сожалению, в возможностях C++20 пока еще не сильно копенгаген, только учусь. Поэтому интересно, а можно ли было сделать лаконичнее и понятнее?
Полный код под катом, а проверить его можно, например, на Wandbox.
Upd. Под катом так же и второй вариант, более компактный за счет отсутствия одного из концептов и использования if constexpr внутри вспомогательной функции low_watermark.
Upd. Более безопасно использовать std::same_as вместо std::is_same_v.