0

クラスTestの簡単な例があります

#include <algorithm>
#include <iterator>
#include <vector>

template <typename T>
struct MinMax { T min, max; };

template <typename T>
using TList = std::vector<T>;

template <typename T>
class Test
{
   private:
      const T a, b;         
      const MinMax <T> m;   
   public:
      Test() : a(0), m{ 0, 0 }, b(0.0) {};
   public:
      T getA() const { return a; }
      MinMax <T> & getMinMax() const { return m; }
      T getB() const { return b; }
      Test(const Test &t) : a(t.a), b(t.b), m(t.m ) {}
};

定数データ メンバーを使用します。コンストラクターの代わりに、データは変更されません。std::inserter を使用して、Test オブジェクトのベクトルを別のベクトルにコピーしたいと考えています。コピーコンストラクタが不十分であることに驚いています

int main()
{
   TList <Test <double> > t1;
   TList <Test <double> > t2;
   Test<double> t;
   t1.push_back(t);
   std::copy(t2.begin(), t2.end(), std::inserter(t1, t1.begin()));

   return 0;
}

次のコンパイラ エラーが表示されます (VS2015)。

Error   C2280   'Test<double> &Test<double>::operator =(const Test<double> &)': attempting to reference a deleted function  Const

データ メンバーを const にして、別の方法でコピーを実行することは可能ですか (いくつかのハック :-))? または、演算子 = を定義する必要があるため、データ メンバーを const にすることはできません (const データ メンバーを持つオブジェクトに代入することはできません)。

ご協力いただきありがとうございます。

4

1 に答える 1

3

a への挿入は、挿入されたvector要素の後のすべての要素を再割り当てし、挿入された要素を解放されたスロットに割り当てます。

つまり、標準では、標準コンテナーの要素が完全な機能を提供する(定義されている)必要があるため、それはできません。Asssignablea = b

自分で書くという明白な解決策とは別に、プッシュバックすることoperator=で const メンバーを持つ要素を a に追加することもできます:vector

std::copy(t2.begin(), t2.end(), std::back_inserter(t1));

しかし、それは一種の標準に反する作業です。push_backたまたま割り当て可能性を必要としませんが、他の機能は可能性があります。

または、挿入に割り当て可能性を必要としないコンテナを使用できます。

template <typename T>
using TList = std::list<T>;

の連続したメモリ キャッシュの局所性のすべての利点をトレードオフしますvector

締めくくりとして、const内部で代入可能性を必要とする汎用コンテナーに関するこのような問題があるため、構造体のデータ メンバーを宣言することを避ける傾向があります。あなたの例では、プライベート メンバーから削除するconstと、十分な読み取り専用フィールドが残ることに注意してください (外部からゲッターを介してのみアクセスできます)。

于 2016-09-17T13:46:55.077 に答える