我試圖創建一個非常簡單的基本C++類來實現線程安全列表,即當您訪問它時會自動鎖定的列表。不幸的是,編譯器不想讓我創建並返回一個包含unique_lock
的結構。這是我最初試圖:不能將一個std :: unique_lock移動到一個struct
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 };
}
};
這種失敗
no matching function for call to ‘LockedQueue<tcp::socket>::LockedListAccess::LockedListAccess(<brace-enclosed initializer list>)
我猜這意味着對於結構不動的工作,括號初始化列表/ C++ 11的統一初始化 - 只有std :: unique_lock類型。所以,我想創造我的結構明確的構造函數的unique_lock作爲右值引用,並將其移動到成員:
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 };
}
};
然而,這也失敗了,給我的錯誤
error: use of deleted function ‘std::unique_lock<_Mutex>::unique_lock(const std::unique_lock<_Mutex>&) [with _Mutex = std::mutex]’
這個編譯器錯誤尤其令人困惑,因爲它指向包含lock(l), access(a)
的行,我試圖使用std :: unique_lock的已刪除副本構造函數。我宣稱l
爲lock_t&&
,所以我怎麼可能調用複製構造函數?
我可以在互聯網上找到的大多數資源似乎表明,你可以用std :: move移動unique_locks,儘管似乎沒有人解決如何通過使用std ::構造一個包含unique_lock的對象的問題。移動。我在這裏做錯了什麼?
哇,這是一個奇怪的語言 「功能。」我永遠不會期望聲明'lock_t &&'的東西突然變成'lock_t&',只是因爲它在構造函數中。而且它看起來沒有必要對已經是右值的東西進行「std :: move」。感謝教我另一個C++的怪癖。 – Edward
它不會成爲'lock_t&'。它仍然是一個綁定到臨時對象的r值引用,但它被用作l值。這一開始讓我感到困惑,但如果你知道什麼是l值,那麼它確實有意義。 I.E:任何被命名的東西都可能是一個l值,而你的'lock_t &&'有一個名字'l'; –