Давайте возьмем реализацию std::unique_lock
из стандартной библиотеки:
struct defer_lock_t { explicit defer_lock_t() = default; };
struct try_to_lock_t { explicit try_to_lock_t() = default; };
struct adopt_lock_t { explicit adopt_lock_t() = default; };
inline constexpr defer_lock_t defer_lock {};
inline constexpr try_to_lock_t try_to_lock {};
inline constexpr adopt_lock_t adopt_lock {};
unique_lock (mutex_type& m, defer_lock_t t) noexcept;
unique_lock (mutex_type& m, try_to_lock_t t);
unique_lock (mutex_type& m, adopt_lock_t t);
Есть ли причина, по которой нельзя / нельзя / не следует использовать перечисления вместо структур для реализации диспетчеризации тегов? Такие как:
enum defer_lock_t { defer_lock };
enum try_to_lock_t { try_to_lock };
enum adopt_lock_t { adopt_lock };
unique_lock (mutex_type& m, defer_lock_t t) noexcept;
unique_lock (mutex_type& m, try_to_lock_t t);
unique_lock (mutex_type& m, adopt_lock_t t);
Последнее является более кратким.
Единственное преимущество использования структур, о которых я могу думать, это наследование (например, теги итератора). Но во всех остальных случаях почему бы не использовать enum?
Во-первых, вы не хотите, чтобы типы тегов были {}
-конструктивен, вы хотите явно назвать их. Это не относится конкретно к unique_lock
поскольку unique_lock<std::mutex> lk(m, {})
было бы неоднозначно, но есть общий принцип. Типы тегов разработаны так, что вы должны написать std::defer_lock
(или, если вы действительно хотите,
std::defer_lock_t()
).
Во-вторых, вы действительно хотите использовать типы тегов только в том контексте, в котором они предназначены для использования. Если вы делаете их enum
с, то вы вносите все enum
функциональность — как быть преобразованным в целые числа:
std::make_unique<int>(std::defer_lock); // ok?
// is this like super deferred?
auto x = std::defer_lock * 2;
// what do you get when you multiply six by nine?
std::unique_lock lk(m, static_cast<std::defer_lock_t>(42));
Эти другие выражения не имеют смысла, поэтому было бы хорошо, чтобы они даже не существовали.
В-третьих, краткость реализации стандартной библиотеки в случае, когда она представляет собой небольшое фиксированное количество символов, на самом деле не является большой проблемой. Так что я бы даже не увидела enum
реализация как победа. Нет тот много типов тегов в стандартной библиотеке.
Других решений пока нет …