Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move an element from std::deque in C++11

We know that std::deque::front() return a reference to a first element of deque. I would to know if this code is always safe:

//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

I've tried this code using gcc-4.9 and works but I don't know if we can consider this code safe!

like image 523
Gian Lorenzo Meocci Avatar asked Jun 15 '14 20:06

Gian Lorenzo Meocci


1 Answers

The std::function move constructor is not guaranteed to not throw exceptions, so you have an exception safety issue. Since you are not using an RAII lock for m, it will remain locked if auto f = move(funs.front()); throws. You can correct the problem with 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
}

or 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
like image 50
Casey Avatar answered Oct 25 '22 19:10

Casey