2

I have written 3 mutex classes TMutex, TCondition and TSpinLock All have a void lock() and a void unlock() member. Now I would like to use std::lock_guard on them. I instatiate lock_guard at the end of my source file for my new mutex classes like this:

template class std::lock_guard<app::TMutex>;
template class std::lock_guard<app::TCondition>;
template class std::lock_guard<app::TSpinLock>;

If I use:

TCondition cond;
std::lock_guard<std::mutex> lock(cond);

I get the following compiler error messages:

../src/inc/threads.cpp:317:39: error: no matching function for call to 'std::lock_guard::lock_guard(app::TCondition&)' ../src/inc/threads.cpp:317:39: note: candidates are: /usr/include/c++/4.6/mutex:447:7: note: std::lock_guard<_Mutex>::lock_guard(std::lock_guard<_Mutex>::mutex_type&, std::adopt_lock_t) [with _Mutex = std::mutex, std::lock_guard<_Mutex>::mutex_type = std::mutex] /usr/include/c++/4.6/mutex:447:7: note: candidate expects 2 arguments, 1 provided /usr/include/c++/4.6/mutex:444:16: note: std::lock_guard<_Mutex>::lock_guard(std::lock_guard<_Mutex>::mutex_type&) [with _Mutex = std::mutex, std::lock_guard<_Mutex>::mutex_type = std::mutex] /usr/include/c++/4.6/mutex:444:16: note: no known conversion for argument 1 from 'app::TCondition' to 'std::lock_guard::mutex_type& {aka std::mutex&}'

I also tried to implement my own lock_guard wrapper as a new template class (very much like the original lock_guard:

template<typename T>
class TLockGuard
{
private:
  typedef T lock_t;
  lock_t&  instance;

public:
  TLockGuard& operator=(const TLockGuard&) = delete;
  explicit TLockGuard(lock_t& F) : instance(F) { instance.lock(); }
  TLockGuard(const TLockGuard&) = delete;
  ~TLockGuard() { instance.unlock(); }
};

and do the similiar instantiation for this class:

template class TLockGuard<app::TMutex>;
template class TLockGuard<app::TCondition>;
template class TLockGuard<app::TSpinLock>;

If I use this template class like this:

TCondition cond;
std::TLockGuard<std::mutex> lock(cond);

I get a different error:

../src/inc/threads.cpp:318:39: error: no matching function for call to 'app::TLockGuard::TLockGuard(app::TCondition&)' ../src/inc/threads.cpp:318:39: note: candidate is: ../src/inc/semaphore.h:164:12: note: app::TLockGuard::TLockGuard(app::TLockGuard::lock_t&) [with T = std::mutex, app::TLockGuard::lock_t = std::mutex] ../src/inc/semaphore.h:164:12: note: no known conversion for argument 1 from 'app::TCondition' to 'app::TLockGuard::lock_t& {aka std::mutex&}'

Can someone help me to understand what is going wrong in both cases? I would prefer to use the standard lock_guard, but it would be nice if my own wrapper will also work.

3
  • 5
    std::lock_guard<TCondition> lock(cond); Commented Oct 6, 2014 at 18:09
  • @dyp Post that as an answer Commented Oct 6, 2014 at 18:10
  • "I instatiate lock_guard at the end of my source file for my new mutex classes like this" I'm not sure what you're trying to achieve with the explicit instantiation. Commented Oct 6, 2014 at 18:12

1 Answer 1

3

The following example compiles fine:

#include <thread>
#include <mutex>

struct Mutex
{
    void lock() {}
    void unlock() {}
};

struct Condition
{
    void lock() {}
    void unlock() {}
};

struct SpinLock
{
    void lock() {}
    void unlock() {}
};

template class std::lock_guard<Mutex>;
template class std::lock_guard<Condition>;
template class std::lock_guard<SpinLock>;


int main()
{
    static Mutex mutex;
    std::lock_guard<Mutex> lock(mutex);
}

You problem is that:

TCondition cond;
std::lock_guard<std::mutex> lock(cond);

You are creating a lock_guard that expects an std::mutex but you passed a TCondition.

try change to:

std::lock_guard<TCondition> lock(cond);
Sign up to request clarification or add additional context in comments.

3 Comments

I'll up vote this if you'll remove the explicit template instantiations of std::lock_guard and maybe mention why they aren't needed. :-)
Many thanks for the hint. You wont believe how many times I stared on these lines ;-) It,s working now...
You don't really need the explicit template instantiations. This would help to speed compilation but I don't think you really get an improvement for that. I would just remove it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.