在C++ 11中从std :: deque移动元素

Gia*_*cci 6 c++ move std deque c++11

我们知道std::deque::front()返回对deque的第一个元素的引用.我想知道这段代码是否总是安全的:

//deque of lambdas
deque<function<void(void)>> funs;

// then is some other place:
// take a lock
m.lock();
auto f = move(funs.front()); // move the first lambda in f
funs.pop_front(); // remove the element from deque //now the value is hold by f
m_.unlock(); // unlock the resorce
f(); //execute f
Run Code Online (Sandbox Code Playgroud)

我已经尝试使用gcc-4.9这个代码并且有效,但我不知道我们是否可以认为这个代码是安全的!

Cas*_*sey 9

std::function移动构造函数不能保证不抛出异常,所以你有一个异常的安全问题.由于您没有使用RAII锁m,因此如果auto f = move(funs.front());抛出它将保持锁定状态.您可以使用以下方法更正问题std::unique_lock:

std::unique_lock<decltype(m)> lock{m};
if (!funs.empty()) {
  auto f = move(funs.front()); // move the first lambda in f
  funs.pop_front(); // remove the element from deque //now the value is hold by f
  lock.unlock(); // unlock the resorce
  f(); //execute f
}
Run Code Online (Sandbox Code Playgroud)

或者std::lock_guard:

function<void()> f;
{
  std::lock_guard<decltype(m)> lock{m};
  if (!funs.empty()) {
    f = move(funs.front()); // move the first lambda in f
    funs.pop_front(); // remove the element from deque //now the value is hold by f
  }
}
if (f) f(); //execute f
Run Code Online (Sandbox Code Playgroud)

  • @GianLorenzoMeocci为什么`auto`会提供更好的性能?第一个片段中的`auto f`将与`decltype(move(funs.front()))f`相同.因此,通过声明`decltype(move(funs.front()))f`在第二个片段中将给出相同的结果. (2认同)