私はコードで以下を宣言しました
vector <const A> mylist;
次のコンパイルエラーが発生します-
new_allocator.h:75: error: `const _Tp* __gnu_cxx::new_allocator<_Tp>::address(const _Tp&) const \[with _Tp = const A]' and `_Tp* __gnu_cxx::new_allocator<_Tp>::address(_Tp&) const [with _Tp = const A]' cannot be overloaded
しかし、宣言した場合-
vector <A> mylist;
私のコードはコンパイルされます。
このコンテキストではconstは許可されていませんか?
みんなの参考のためにここに私のコードをコピーしています-
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A () {cout << "default constructor\n";}
A (int i): m(i) {cout << "non-default constructor\n";}
private:
int m;
};
int main (void)
{
vector<const A> mylist;
mylist.Push_back(1);
return 0;
}
ベクター内のアイテムは割り当て可能でなければなりません(または、標準のより新しいバージョンでは、移動可能)。 const
オブジェクトは割り当て可能ではないため、それらをベクトルに格納しようとすると失敗します(または少なくともcan fail-コードは無効ですが、コンパイラは自由にそれを受け入れることができます)とにかく、それが選択した場合、ほとんどのプログラマーは一般的に無効なコードを拒否することを好みますが)。
本当に知識が豊富であると思いますが、ひどくやりたい場合は、const
であっても割り当て可能な型を次のように定義できます。
class ugly {
mutable int x;
public:
ugly const &operator=(ugly const &u) const {
x = u.x;
return *this;
}
};
私はあなたがそうだと信じていますすべきvector
であっても、このタイプのアイテムをconst
に保存できます。これらのベクトルを作成する簡単なテストは、VC++で成功します。これは一部の古いコンパイラでは失敗しましたが(たとえば、g ++ 4.8.1で失敗しました)、かなり最近のコンパイラ(VC++は少なくとも2015年に戻って、g ++は少なくとも5.4に戻って、clang ++は少なくとも4.0に戻っています)で動作します。それをサポートするそれぞれの最初のバージョンを追跡しようとしました。
現在のコンパイラーでは、const
オブジェクトの移動をサポートするタイプがおそらく同様に機能します。しかし、それが明白ではなかった場合に備えて、const
とマークされていても、これによりオブジェクトを変更できます。これは明らかに、ユーザーの合理的な期待に対する直接の違反であるため、ほとんどの場合問題であり、解決策ではありません。
Push_back
メソッドの使用が問題です。 emplace_back
がコンパイルされます。別の代替方法(ここで説明しない状況全体に依存します)は、挿入されたアイテムがベクトルの外側にある場合、vector<A const&>
を使用することです。ベクトル内の項目は割り当て可能である必要はありませんが、割り当て可能でない場合、一部のメンバー関数とアルゴリズムを使用できません。
説明:
Push_back
は、firstのデフォルトでベクトル内にAを構築し、then指定された参照を(copy-constructを使用して)割り当てます。これはconst
資格を破るので、コンパイルされません。
emplace_back
は「完全転送」を使用して、実際のコンストラクターを直接呼び出します。