2

私は STL に慣れてきたばかりでoperator []、エラーが発生する理由がよくわかりません。

        int main(){
          set< int > s;
          for(int i=0; i<=1000; i++) s.insert((i*1777)%123);
          for(int i=0; i<s.size(); i++) cout<<s[i]<<endl;
        }

次に、これを試したところ、別のエラーメッセージが表示されました

        int main(){
          set< int > s;
          for(int i=0; i<=1000; i++) s.insert((i*1777)%123);
          for(int i=0; i<s.size(); i++) cout<<*(s.begin() + i)<<endl;
        }

push_back、および allのようなメンバーがない理由は理解していpop_backますが、これら2つの参照方法が機能しない理由がわかりません(しかし、vectorおよびに対しては機能しますstring)。これらの演算子がライブラリでオーバーロードされていないことは理解していますが、なぜですか?

いくつかのWeb検索の後、私はそれを参照する方法を見つけました

        int main(){
          set< int > s;
          for(int i=0; i<=1000; i++) s.insert((i*1777)%123);
          for(set< int >::iterator i=s.begin(); i!=s.end(); i++) cout<<*i<<endl;
        }
4

5 に答える 5

1

STL セットは添字演算子をオーバーロードしません[]。などの他のコンテナーのように、添え字演算子を直接使用して STL セット要素にアクセスすることはできませんvector。ここで STL セットの完全なリファレンスを見つけることができます: STL セット

于 2013-04-12T19:14:15.017 に答える
1

まあ、それはセットの性質上、完全に理解std::setできる添字を提供していないためです。operator[]set[4] とはどういう意味ですか? 数学的にこれは正しくありません。数学では set1={1,2,3,4} と set2={4,3,2,1} は等しいので、これらのセットの 2 つの set1[n] と set2[n] ごとにどのように真になるか違いますか(std::setただし、要素がソートされている場合は同じになります)?したがってstd::set、添え字はありませんがoperator[]、このコンテナーを反復処理することはできます。

int myints1[]= {10,20,30,40,50};
int myints2[]= {50,40,30,20,10}; 
std::set<int> s1 (myints1,myints1+5);
std::set<int> s2(myints2,myints2+5); // Internally, the elements in a set are 
                                     // always sorted following a specific strict
                                     // weak ordering criterion indicated by its
                                     // internal comparison object, so this set
                                     // will be the same as s2
if(s1==s2){
    printf("sets: true");
}else printf("sets: false");
std::set<int>::iterator it2=s2.begin();
for(std::set<int>::iterator it1=s1.begin();it1!=s1.end();it1++){
            printf("\ns1: %d  s2: %d",*it1,*it2);
    it2++;
}

出力:

セット: 真

s1: 10 s2: 10

s1: 20 s2: 20

s1: 30 s2: 30

s1: 40 s2: 40

s1: 50 s2: 50

于 2013-04-12T19:14:17.420 に答える
1

T& operator[](std::size_t)@BenjaminLindleyは、すべてのランダムアクセスループが複雑になるため、ランダムアクセスイテレーターのないコンテナーには意味がないことを指摘していますO(N^2)(要素の外側のループでは線形でありstd::advance、イテレーターの時間は線形です)。そのため、Sequence Containersstd::arrayのうち、 、std::vectorおよびstd::dequeprovideのみが提供されますoperator[]が、std::list(双方向反復子) およびstd::forward_list(前方反復子) は提供されません。

順序付き連想コンテナー( std::set、、std::mapおよびそれらの複数のいとこ) は双方向反復子のみを提供し、順序付けられていない連想コンテナー(およびそれらの複数のいとこ) は少なくとも前方反復子を持ちます。彼らはまた、メンバーとして持っていません。したがって、代わりにを記述する必要があります。これにより、そのような呼び出しの複雑さが痛々しいほど明白になります。std::unordered_setstd::unorderd_mapoperator[](std::size_t)std::advance(my_set.begin(), n)my_set[n]O(N)

追加のメモとして: マップのようなコンテナーにはキーと値のペアが含まれ、これらのコンテナーの連想的な性質は別の によって表現operator[]されますが、オフセットによってインデックス付けされるのではなく、「関連付けられた」キーを使用して署名Value& operator[](Key const&)(およびC++11 以降の右辺値参照オーバーロード)。これらの演算子は、 の複雑さを持ち、O(log N)の複雑さstd::mapを償却O(1)std::unordered_mapます。これにより、たとえば、これらのコンテナーのすべてのキーに対するループO(N log N)O(N)複雑さがそれぞれ与えられます。

連想operator[]バージョンには挿入セマンティクスもあります。 like の呼び出しはmy_map[my_key] = my_value;、ペアをマップに挿入しようとしmy_key, my_value、そのような要素が既に存在する場合は反復子を返します。constこれらの連想要素アクセスのオーバーロードでもないことに注意してください。そのためにはfind()メンバー関数を使用してください。

キーがそれ自体に関連付けられているという事実を表現するだけであり、挿入セマンティクスはメンバー関数を介してより直接的に表現されているためstd::set、オーバーロードoperator[](Key const&)は意味をなさないためです。insert()

于 2013-04-12T20:34:03.767 に答える