Inn*_*der 10 c++ c++17 tag-dispatching
让我们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);
Run Code Online (Sandbox Code Playgroud)
是否有人不会/不能/不应该使用枚举而不是结构来实现标签调度?如:
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);
Run Code Online (Sandbox Code Playgroud)
后者更简洁.
使用我可以想到的结构的唯一优点是继承(例如,迭代器标记).但在所有其他情况下,为什么不使用枚举?
Bar*_*rry 11
首先,您不希望标记类型是可{}构造的,您希望明确命名它们.这并不具体适用于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));
Run Code Online (Sandbox Code Playgroud)
这些其他表达没有任何意义,所以即使它们存在也不错.
第三,在只是一个小的,固定数量的字符的情况下实现标准库的简洁并不是一个大问题.所以我甚至不认为enum实施是一场胜利.标准库中没有那么多标记类型.
| 归档时间: |
|
| 查看次数: |
357 次 |
| 最近记录: |