5

以下はダメです。

vector<const int> vec;

問題は、テンプレート タイプを割り当て可能にする必要があることです。次のコードは [EDIT: in Visual Studio 2010] をコンパイルし、上記の問題を示しています。

vector<const int> vec;
vec.push_back(6);
vec[0] += 4;

より複雑なタイプでは、これは深刻な問題になる可能性があります。

私の最初の質問は、この動作に理由があるかどうかです。上記を許可しない const コンテナーとそれを許可する非 const コンテナーを作成できるように思えます。

第二に、このように機能するコンテナを作成する方法はありますか?

3 番目に、実際にここで (ユーザー タイプで) 何が起こっているのでしょうか? 私はそれが未定義の動作であることを認識していますが、STL はこれをどのようにコンパイルしているのでしょうか?

4

1 に答える 1

3

許可されていない理由std::vector<T const>は、最初とは異なる場所に挿入する場合、ベクター内のオブジェクトを再シャッフルする必要がある可能性があるためです。現在、メンバーstd::vector<T>::push_back(T const& v)は概念的に同等です (この議論には関係がないため、アロケーター テンプレート パラメーターは省略しています)。

template <typename T>
void std::vector<T>::push_back(T const& v) {
    this->insert(this->end(), v);
}

これは、一部の実装での実装方法のようです。現在、この操作では、一般に、一部のオブジェクトを移動する必要がある可能性があるため、T引数を割り当て可能にする必要があります。MSVC++ に同梱されている標準ライブラリは操作を委譲していないようですが、必要なすべての処理 (つまり、配列のサイズ変更と、スペースが不足したときにオブジェクトを適切に移動する) を行っているようですpush_back()T使用できるタイプの要件が何であるかは明確ではありませんpush_back()

T constただし、原則として、両方をサポートするコンテナとinsert()途中での操作は可能です。インターフェイスでを公開するT以外に、内部ストレージを必要とするものはありません。-version ofoperations likeについては少し注意する必要があります。なぜなら、あるタイプのときに戻り値のタイプとして使用するだけでtype になるからです。C++ 2003 ではこれはエラーになりますが、C++ 2011 では単に折りたたまれていると思います。安全のために、 を使用できます。typename std::remove_const<T>::typeT&constoperator[]()T const&TS constS const constconsttypename std::add_const<T>::type&

于 2012-11-18T18:08:26.520 に答える