I'm trying to create a very simple, bare-bones C++ class to implement a thread-safe list, i.e. one which is automatically locked when you access it. Unfortunately, the compiler doesn't want to allow me to create and return a struct that contains a unique_lock
. This is what I tried at first:
template<typename T>
struct LockedQueue {
private:
std::mutex mutex;
using lock_t = std::unique_lock<std::mutex>;
std::list<T> underlying_list;
public:
struct LockedListAccess {
private:
lock_t lock;
public:
std::list<T> &access;
};
LockedListAccess locked() {
return LockedListAccess{ lock_t{mutex}, underlying_list };
}
};
This fails with
no matching function for call to ‘LockedQueue<tcp::socket>::LockedListAccess::LockedListAccess(<brace-enclosed initializer list>)
I'm guessing this means that brace initializer lists/C++11 unified initialization for structs don't work with move-only types like std::unique_lock. So I tried creating an explicit constructor for my struct that takes the unique_lock as an rvalue reference, and moves it into the member:
template<typename T>
struct LockedQueue {
private:
std::mutex mutex;
using lock_t = std::unique_lock<std::mutex>;
std::list<T> underlying_list;
public:
struct LockedListAccess {
private:
lock_t lock;
public:
std::list<T> &access;
LockedListAccess(lock_t&& l, std::list<T>& a) :
lock(l), access(a) {};
};
LockedListAccess locked() {
return LockedListAccess{ std::move(lock_t{mutex}), underlying_list };
}
};
However, this also fails, giving me the error
error: use of deleted function ‘std::unique_lock<_Mutex>::unique_lock(const std::unique_lock<_Mutex>&) [with _Mutex = std::mutex]’
This compiler error is especially confusing, because it points at the line containing lock(l), access(a)
as the one where I'm trying to use the deleted copy constructor of std::unique_lock. I declared l
as a lock_t&&
, so how could I possibly be calling the copy constructor?
Most resources I could find on the internet seem to indicate that you can move unique_locks around with std::move, though no one seems to address the question of how to construct an object that contains a unique_lock by using std::move. What could I be doing wrong here?
Aucun commentaire:
Enregistrer un commentaire