12

次のコードを検討してください。

struct s
{
    const int id;

    s(int _id):
        id(_id)
    {}
};
// ...
vector<s> v;  v.push_back(s(1));

「const int id」はデフォルトの代入演算子を使用できないというコンパイラ エラーが発生します。

Q1. push_back() に代入演算子が必要なのはなぜですか?
A1. 現在のC++標準がそう言っているからです。

Q2. 私は何をすべきか?

  • const指定子を手放したくない
  • データをコピーしたい

A2. スマートポインターを使用します。

Q3. 私はかなり狂っているように見える「解決策」を思いつきました:

s& operator =(const s& m)
{
    if(this == &m) return *this;
    this->~s();
    return *new(this) s(m);
}

私はこれを避けるべきですか、なぜですか (もしそうなら)? オブジェクトがスタック上にある場合、placement new を使用しても安全ですか?

4

7 に答える 7

5

C++03 では、コンテナーに格納される要素はCopyConstructibleand である必要がありますAssignable(§23.1 を参照)。したがって、実装は、適切と思われるコピーの構築と代入を使用することを決定できます。これらの制約は、C++11 では緩和されています。明示的に、push_back操作の要件は、型がCopyInsertableベクトルにあることです (§23.2.3 シーケンス コンテナーを参照してください)。

さらに、C++11 コンテナーは、挿入操作および do on で移動セマンティクスを使用できます。

于 2012-07-22T16:49:02.567 に答える
4

const指定子を手放したくない

まあ、あなたには選択の余地がありません。

s& operator =(const s& m) {
    return *new(this) s(m); 
}

未定義の動作。

constほとんど誰もメンバー変数を使用しないのには理由があり、それが原因です。それについてあなたができることは何もありません。constメンバー変数は、割り当て可能にしたい型では使用できません。これらの型は不変であり、それだけです。実装には可変性がvector必要です。

于 2012-07-22T17:06:15.877 に答える
1

Q2. 私は何をすべきか?

できればスマートなポインターを格納します。

vector<unique_ptr<s>> v;
v.emplace_back(new s(1));
于 2012-07-22T17:03:16.010 に答える
0

これは実際の解決策ではありませんが、回避策です。

#include <vector>
struct s
{
  const int id;
  s(int _id):
    id(_id)
    {}
};

int main(){
  std::vector<s*> v;  
  v.push_back(new s(1));
  return 0;
}

sこれにより、オブジェクト自体の代わりにポインターが格納されます。少なくともそれはコンパイルされます... ;)

編集:スマートな c++11 ポインターを使用してこれを強化できます。Benjamin Lindley の回答を参照してください。

于 2012-07-22T17:10:02.243 に答える
-3

代入演算子で const_cast を使用します。

S& operator=(const S& rhs)
{
    if(this==&rhs) return *this;
    int *pid=const_cast<int*>(&this->id);
    *pid=rhs.id;
    return *this;
}
于 2013-02-21T16:05:48.770 に答える