1

Scott Meyers の「Effective Modern C++」で、彼は次のように書いています。

は移動のみの型 (つまり、移動はできるがコピーはできない型) であるため、 に追加するとstd::mutex、コピーできなくなるという副作用があります。ただし、移動は可能です。mPolynomialPolynomial

std::mutex mここで、クラスの const メンバー変数へのアクセスを保護する必要がある理由を説明するコンテキストで、クラスにメンバー変数として aを追加しPolynomialます (マルチスレッド中)。私は彼が説明した概念を理解しました。std::mutexしかし、もう少し説明する必要があるのは、「クラスに移動のみのタイプを追加すると、そのクラスが移動のみのタイプとしてコピー不可になるのはなぜですか」ということstd::atomicです。クラスに移動のみの型の変数を追加してもコピー操作を実行したい場合、どうすればそれを乗り越えることができますか?

4

3 に答える 3

2

「移動専用タイプをクラスに追加すると、そのクラスが移動専用タイプとしてコピー不可になる理由」

これは完全に真実ではありません。コピー不可能なメンバー変数を追加すると、 のようなものを書くことType (const Type& t) = default;ができなくなりますが、コピー不可能なメンバーを無視する独自のコピー コンストラクターを実装することはできます。

class Type{

int integer;
std::mutex m;

public:
Type() = default;
Type(const Type& rhs): integer (rhs.integer){}

}

これ以外にも、移動のみのメンバーを含むオブジェクトの例を多数見つけることができますが、開発者が移動コンストラクターを削除したという理由だけで、それら自体は移動できません。

std::mutex や std::atomic のようなタイプがデフォルトで移動のみのタイプなのはなぜですか?

どちらも移動コンストラクターを実装していません。これは間違った記述です。

于 2016-03-29T13:06:08.410 に答える
1

std::mutex標準がそう言っているという理由だけでコピー可能ではありません。std::mutex彼らはおそらくコピー可能なものを書くことができたでしょうが、そうしないことにしました。

推測として、コピー不可のstd::mutex方が効率的で、安全で、理解しやすいかもしれません。

例として、より安全で理解しやすい理由を以下に示しますstd::mutex。私は、個人的に、正しい答えが何かわかりません。正解は「それはナンセンス」だと思います。「最小の驚きの答え」はありません。

同時実行コードで驚くべき答えが得られる代わりに、コピーをブロックすることで問題を回避します。コピーしたいミューテックスを保存する人は、何をしたいかを自分で決める必要があります。


C++ は、状況によってはコピー コンストラクターを自動的に生成します。より多くの状況では、あなたがそれMyClass(MyClass const&)=defaultを求めたときにそれを実行して書くことができます。

クラスにコピー不可能なクラスが含まれている場合、クラスは生成されず、それを要求することはできません。これは、生成されたコピー コンストラクターが基本的にそのメンバーをコピーするためです。メンバーをコピーできない場合は、コピー コンストラクターを生成できません。


標準がそうmutex言っているので、コピーすることはできません。

構造体またはクラスにコピーできないメンバーが含まれている場合、既定のコピー コンストラクターは使用できません。明示的に自分で書く必要があります。


型が を格納する必要がある場合、mutex他のすべてのメンバーを手動でコピーするコピー ctor を維持しなければならないという頭痛を防ぐための 1 つの方法は、非mutex状態をサブ構造体に貼り付けてから、その既定のコピーを使用することです。mutex次に、コピー中に何をするかを決定し、コピー ctor (および代入コピー演算子) はシンプルなままです。

struct bob_with_mutex {
  sturct bob_simple_data {
    int x, y, z;
    std::vector<char> buff;
  };

  bob_simple_data data;
  std::mutex m;

  bob_with_mutex( bob_with_mutex const& o ):
    data(o.data)
  {}
  bob_with_mutex& operator=( bob_with_mutex const& o )
  {
    data = o.data;
    return *this;
  }
};

この型bobにはミューテックスと一部のデータが混在しています。データはサブ構造体に格納されます。の copy ctor をbob_with_mutexデフォルトにすることはできませんが、単に「データをコピーし、それ以外は何もコピーしない」と言っています。

のコピーにはbob独自のミューテックスがあります。

于 2016-03-29T13:44:49.077 に答える
-1

1 つの可能性は、ミューテックスの型をミューテックスへのポインターに変更することです。ポインターをコピーすることはできますが、ミューテックスのコピーは 1 つしかありません。スマート ポインターを使用することもできます。

于 2016-03-29T13:17:39.513 に答える