非常に単純な、ベアボーンのC++クラスを作成して、スレッドセーフなリスト、つまりアクセス時に自動的にロックされるリストを実装しようとしています。残念ながら、コンパイラは、unique_lock
を含む構造体を作成して返すことを許可したくありません。これは私が最初に試したものです:構造体にstd :: 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 locked() {
return LockedListAccess{ lock_t{mutex}, underlying_list };
}
};
これは、私は、これは構造体のためのブレース初期化子リスト/ C++ 11統一初期化は移動では動作しないことを意味推測している
no matching function for call to ‘LockedQueue<tcp::socket>::LockedListAccess::LockedListAccess(<brace-enclosed initializer list>)
で失敗します-only :: 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]’
私にエラーを与えてこのコンパイラエラーは、私がstd :: unique_lockの削除されたコピーコンストラクタを使用しようとしているものとしてlock(l), access(a)
を含む行を指しているので、特に混乱します。私はl
をlock_t&&
と宣言しました。だから、どうすればコピーコンストラクタを呼び出すことができますか?
私はインターネット上で見つけることができるほとんどのリソースは、あなたがstd :: moveでunique_locksを移動できることを示しているようですが、誰もstd ::を使ってunique_lockを含むオブジェクトを構築する方法の問題に対処できないようです動く私はここで何が間違っていますか?
うわー、それは奇妙な言語です私は 'lock_t &&'がコンストラクタ内にあるからというだけで突然' lock_t& 'になるとは思わないでしょう。そして既に 'rvalue 'であるものを' std :: move'する必要はありません。私に別のC++の奇妙なことを教えてくれてありがとう。 – Edward
'lock_t&'にはなりません。これはまだtempオブジェクトにバインドされているr値参照ですが、l値として使用されます。これは当初私を混乱させましたが、l値が何であるかを知っていれば実際には理にかなっています。 I.E:命名されたものはたぶんl-valueであり、 'lock_t &&'は' l'という名前です。 –