1
votes

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.

1
std::lock_guard<TCondition> lock(cond);dyp
@dyp Post that as an answerStephan Dollberg
"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.dyp

1 Answers

3
votes

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);