ここでの 3 つのソリューション:
1. ポインターを使用する- 簡単な解決策は、ポインターのコンテナーにすることshared_ptr
です。
オブジェクトが真にコピー不可能であり、他のコンテナを使用できない場合、これは「良い」解決策です。
2. その他のコンテナー - または、非コピー コンテナー (インプレース構築を使用する) を使用することもできますが、それらはあまり一般的ではなく、STL との互換性がほとんどありません。(ちょっとやってみたけどダメだった)
オブジェクトが真にコピー不可能であり、ポインターを使用できない場合、それは「神」の解決策になります。
[編集] C++13 では、std::vector はインプレース構築 (emplace_back) を許可し、移動セマンティクスを実装するコピー不可能なオブジェクトに使用できます。[/編集]
3. コピー可能性を修正する- クラスがそのままコピー可能であり、mutex がそうでない場合、コピー コンストラクターと代入演算子を「単純に」修正する必要があります。
通常、ミューテックスを除くすべてのメンバーをコピーして割り当てる必要があるため、それらを記述するのは面倒ですが、多くの場合、次の方法で簡略化できます。
template <typename TNonCopyable>
struct NeverCopy : public T
{
NeverCopy() {}
NeverCopy(T const & rhs) {}
NeverCopy<T> & operator=(T const & rhs) { return *this; }
}
そして、ミューテックスメンバーを
NeverCopy<Mutex> m_mutex;
残念ながら、そのテンプレートを使用すると、Mutex の特別なコンストラクターが失われます。
[編集] 警告:コピー CTor/代入を「修正」するには、多くの場合、コピー コンストラクトで右側をロックし、代入で両側をロックする必要があります。残念ながら、copy ctor/assignment をオーバーライドしてデフォルトの実装を呼び出す方法はありません。そのため、このトリックNeverCopy
は外部ロックなしでは機能しない可能性があります。(独自の制限がある他のいくつかの回避策があります。)