2011-12-31 4 views
8

以下のコードを見てください。私はベクトルにconstオブジェクトを入れようとしています。私は答えが「STLコンテナは、オブジェクトを割り当て可能でコピー可能でなければなりません」ということを知っていますが、標準を引用することなく、誰でもこれを行う問題が何であるか説明できますか?私はなぜこのようなクラスをコピーできないのか理解できません。(それ以外にもC++は許可しません)。なぜSTLコンテナにconstオブジェクトを置くことができないのですか?

変更が許可されていない値が格納されています。なぜ、ベクターに入れることができないのですか?単にこれらのオブジェクトの別のものを作成するだけですか?

#include <vector> 

// Attempt 1 
// /home/doriad/Test/Test.cxx:3:8: error: non-static const member ‘const int MyClass::x’, can’t use default assignment operator 

// struct MyClass 
// { 
// int const x; 
// MyClass(int x): x(x) {} 
// }; 
// 
// int main() 
// { 
// std::vector<MyClass> vec; 
// vec.push_back(MyClass(3)); 
// return 0; 
// } 

// Attempt 2 
// /home/doriad/Test/Test.cxx:28:23: error: assignment of read-only member ‘MyClass::x’ 
struct MyClass 
{ 
    int const x; 
    MyClass(int x): x(x) {} 
    MyClass& operator= (const MyClass& other) 
    { 
    if (this != &other) 
    { 
     this->x = other.x; 
    } 

    return *this; 
    } 
}; 

int main() 
{ 
    std::vector<MyClass> vec; 
    vec.push_back(MyClass(3)); 
    return 0; 
} 

EDIT:

はstd ::設定とstd ::リストでこれを行うことが可能です。私はそれが割り当てを使用するstd :: vectorのsort()関数だと思います。これはUBの権利ではないのですか?

#include <set> 

// Attempt 1 
struct MyClass 
{ 
    int const x; 
    MyClass(int x): x(x) {} 
    bool operator< (const MyClass &other) const; 
}; 

bool MyClass::operator<(const MyClass &other) const 
{ 
    if(this->x < other.x) 
    { 
    return true; 
    } 
    else if (other.x < this->x) 
    { 
    return false; 
    } 

} 


int main() 
{ 
    std::set<MyClass> container; 
    container.insert(MyClass(3)); 
    return 0; 
} 
+0

Semi-related:http://stackoverflow.com/questions/2759350/embarassing-c-question-regarding-const/2759426#2759426 – cHao

+0

std :: vectorの代わりにstd :: setを使って私の編集を見てください。これでいい? –

+0

@David:C++ 03では、 'std :: set <>'を使っているように、依然として不正です - §23.1/ 3では、要素型はコピーコンストラクタブルとアサイン可能でなければなりません。 C++ 11では、コードは整形式ですが、 'MyClass'が代入不可能なため、' std :: set <> 'インスタンスは代入されません。 (また、セミ関連: 'operator-'実装は壊れています、 'this-> x == other.x'なら値を返しません)。 – ildjarn

答えて

6

EDIT2:vectordequeためinsert方法(およびそのことについてはpush_backのデフォルトの実装)が必要であることをC++ 11標準状態(仕事を持っていない原料の束を削除します)値の型がCopyAssignableすること、すなわち、値がサポートされています。constメンバーと

t= v; 

クラスと構造体は、デフォルトではないCopyAssignableあるので、あなたは動作しません何をしたいのか。

この文書(n3173)には、さまざまなコンテナ要件が説明されています。

+2

MSN:それを動作させるには何が必要ですか?私は代入演算子を実装する必要がありましたが、constなので代入はできません! –

+1

@David:constデータメンバを単純に避けてください。あなたのクラスが適切なconst正しいgetterを提供しているなら、それらは役に立たないでしょう。 – ildjarn

+2

これはハックのように思えますが、「正しい」ものではありません。 –

0

MyClass型のオブジェクトをstd :: vectorに配置すると、ベクターは、渡されたオブジェクトではなく、保存用のオブジェクトのコピーを作成します。

+1

確かに意味があります。しかし、なぜconst値を持つオブジェクトをコピーできないのですか?それはちょうど同じconst値を持つ新しいオブジェクトを作ることができるでしょうか? –

+0

@David:確かに、あなたは依然として「割り当て可能」要件を欠いています。 – ildjarn

1

可能な解決策の1つは、ポインターが割り当て可能でありコピー可能であるため、ベクターへのオブジェクトへのポインターを格納することです。

別の可能な解決策は、(つまり、あなたがプライベートとして宣言する必要があり、どこコンストラクタ外部から変更しないでください)constキーワードなしのxを宣言し、それがカプセル化によって変更することができないことを保証するだろう。..

関連する問題