
Howard Hinnant wrote:
I sat down to write a realistic example of when a "try_lock" constructor might be sufficiently desirable to warrant its existence:
[...]
template <class Job> void do_jobs(std::vector<Job>& v) { typedef typename Job::Mutex Mutex; typedef typename Mutex::scoped_lock Lock; for (typename std::vector<Job>::iterator i = v.begin(), e = v.end(); i != e; ++i) { Lock lock(*i->mut_, try_lock); if (lock && i->needs_executing_) { i->needs_executing_ = false; i->f_(); } } }
Then I rewrote do_jobs for the case where I have no try-lock ctor:
template <class Job> void do_jobs2(std::vector<Job>& v) { using namespace Metrowerks; typedef typename Job::Mutex Mutex; typedef typename Mutex::scoped_lock Lock; for (typename std::vector<Job>::iterator i = v.begin(), e = v.end(); i != e; ++i) { Lock lock(*i->mut_, defer_lock); if (lock.try_lock() && i->needs_executing_) { i->needs_executing_ = false; i->f_(); } } }
You really have to squint to see the difference. ... And I just wrote AND erased several paragraphs proposing that we eliminate the try and timed constructors, but also how I did not feel strongly either way! :-)
But I just noticed a difference (apparently I didn't squint enough the first time ;-) ).
The loop in do_jobs is no-throw if i->f_() is no-throw. The same loop in do_jobs2 should be no-throw as well, and it is, but the compiler doesn't know it. That is, the statement:
lock.try_lock()
hides the test:
if (locked_) throw lock_error();
This is an unnecessary run time inefficiency.
Interesting point. I really hoped that compilers are good enough to inline the constructor and try_lock and eliminate the dead code. But it doesn't seem so. The question is, is this an argument in favor of the try_lock constructor, or an argument against the if( locked_ ) overhead in the try_lock member function? As for the constructor vs member function: a counterpoint: consider what happens when the programmer omits the if(lock) test by mistake. I'm not saying that this is a particularly compelling argument, by the way, but you may feel differently.