首页 > 解决方案 > if-initializer 中的 lock_guard 初始化,而不是简单的作用域

问题描述

是否正确

if (std::lock_guard lk(m_state.mtx); true) {
  m_state.aborting = true;
}

{
  std::lock_guard lk(m_state.mtx)
  m_state.aborting = true;
}

100% 相同吗?


这是我的问题的背景:在Mastering the C++17 STL中,作者给出了一个线程池的代码示例。它包含以下块(第 208 页):

~ThreadPool() {
  if (std::lock_guard lk(m_state.mtx); true) {  // <<--- Line of interest
    m_state.aborting = true;
  }

  m_cv.notify_all();
  for (std::thread& t : m_workers) { 
    t.join();
  }
}

标记的行使用 if 语句的初始化部分来创建 lock_guard。这已在其他问题中使用,以将 lock_guard 的范围限制为 if 语句,同时还保护 if 语句本身的评估。

在这个例子中让我感到困惑的是 if 语句没有适当的条件。根据if 上的 cppreference 页面

如果使用 init 语句,则 if 语句等价于

{
  init_statement
  if ( condition )
    statement-true
}

在这种情况下,这意味着if (std::lock_guard lk(m_state.mtx); true) {...}相当于

{
  std::lock_guard lk(m_state.mtx);
  if (true) {
    m_state.aborting = true;
  }
}

我是否错过了这不是 100% 相同的情况,或者是用 if 语句编写它的充分理由?

下一页的不同示例中使用了相同的模式,所以我认为它是故意完成的,而不是在实际情况下的剩余部分。

标签: c++scopec++17

解决方案


它们在语义上是相同的。由于这本书似乎都是关于新的 C++ 17 特性的,所以作者使用它是有道理的。但要小心:每一个新功能都将被滥用,直到尘埃落定,共同智慧就使用该功能的好方法和坏方法达成共识。

在我的拙见中,这种方式只会增加混乱(如果块被无条件执行,为什么会有一个 if 构造?),我更喜欢简单的块。时间会证明作者的方式是否会成为可接受的或不受欢迎的构造。或者,如果没有人会关心,或者它是否会永远存在争议。


推荐阅读