C ++ 17 — Использование enum вместо struct для диспетчеризации тегов в Stack Overflow

Давайте возьмем реализацию 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?

10

Решение

Во-первых, вы не хотите, чтобы типы тегов были {}-конструктивен, вы хотите явно назвать их. Это не относится конкретно к 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 реализация как победа. Нет тот много типов тегов в стандартной библиотеке.

11

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]