C ++中tag和enum dispatch之间有什么区别?

时间:2017-11-09 10:54:46

标签: c++ enums tags

std::unique_lock有几个构造函数接受xxx_lock_t。这些是空结构:

struct adopt_lock_t {};
struct defer_lock_t {};
struct try_to_lock_t {};

它们对应的值如下。

constexpr adopt_lock_t  adopt_lock {};
constexpr defer_lock_t  defer_lock {};
constexpr try_to_lock_t try_to_lock {};

最后,这里是std::unique_lock的构造函数。

unique_lock (mutex_type& m, adopt_lock_t tag);
unique_lock (mutex_type& m, defer_lock_t tag) noexcept;
unique_lock (mutex_type& m, try_to_lock_t tag);

我的问题是:

为什么他们使用这种标签而不是枚举类型?

我认为通过使用枚举,我们不需要为每种类型的锁定声明构造函数。我也同意通过实现每个类型的构造函数,它不需要比较实现中给出的锁类型。

主要原因是什么?

2 个答案:

答案 0 :(得分:4)

如果使用enum,则必须在运行时确定锁定时选择的模式,àla:

if(mode == lock::adopt_lock) {
   ...
} else if(mode == lock::defer_lock) {
   ...
}
else ...

使用重载,您可以将此区别移至编译时。

答案 1 :(得分:2)

  

我也同意通过实现每个类型的构造函数,它不需要比较实现中给出的锁类型

但你明白这意味着什么吗?无论采用哪种方法,c都只会进行一种类型的锁定。但是,如果分支在c,那么每个人都会为此付出代价。即使是那些事先知道他们会采取什么分支的人。 C ++就是不付出你不需要的开销。像这样实现它可以实现以下目的:

  1. 如果您事先知道自己将如何锁定,则无需为任何分支付费。

  2. 如果您事先不知道,您可以轻松自行分支。它将需要默认构造锁,并(移动)分配给它。但无论如何,这两项行动相当便宜。它不会给分支机构增加太多的成本。