43

コードで次のように宣言しました

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;
}
4

2 に答える 2

38

ベクトル内のアイテムは割り当て可能 (または、標準の最新バージョンでは移動可能) でなければなりません。constオブジェクトは割り当て可能ではないため、それらをベクトルに格納しようとすると失敗します (または少なくとも失敗する可能性があります。コードは無効ですが、コンパイラは、選択した場合はとにかく自由に受け入れることができますが、ほとんどのプログラマーは一般的に好むでしょう)その無効なコードは拒否されます)。

本当に衒学的な人のために、もしあなたが十分にひどくしたいのであれば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 に戻ります。 t は、それをサポートしたそれぞれの最初のバージョンを突き止めようとしました)。

現在のコンパイラの場合、constオブジェクトの移動をサポートする型はおそらく同様に機能します。しかし、それが明らかでない場合に備えて: これにより、 とマークされていても、オブジェクトを変更できますconst。これは、合理的なユーザーの期待に直接違反していることは明らかです。そのため、これはほとんど問題であり、解決策ではありません。

于 2013-06-26T06:36:08.333 に答える