std::vector<double> v; std::multiset s; std::list<std::string> ls; // ... std::vector<double>::iterator i = v.begin(); std::multiset::const_iterator ci = s.begin(); std::list<std::string>::iterator li = ls.begin(); I
Meddig hivatkozik az iter´ator az ottl´ev˝o elemre?
I
Meddig hivatkozik az iter´ator ´erv´enyes t´arter¨ uletre?
Halad´ o C++, 4/ 78
Kont´enerek
fel´ep. Iter´ator Invalid I
vector din.t¨omb Random Reallok´aci´o
deque fix m´eret˝ u t¨omb¨ok Random (*)
list l´ancolt lista BiDir Soha
asszoc. P-F BiDir Soha
(*): I
I
I
I
besz´ ur´askor fel kell tenni, hogy az iter´atorok ´erv´enytelenn´e v´alnak a deque k¨ozep´eb˝ol t¨ort´en˝o t¨orl´eskor fel kell tenni, hogy az iter´atorok ´erv´enytelenn´e v´alnak a deque valamely sz´el´er˝ol t¨ort´en˝o t¨orl´es csak a t¨or¨olt iter´atort ´erv´enytelen´ıti a deque iter´atorai ´erv´enytelenn´e v´alhatnak an´elk¨ ul, hogy az elemeire hivatkoz´o referenci´ak ´es pointerek is invalid´al´odn´anak Halad´ o C++, 5/ 78
Iter´ator invalid´aci´o
std::list n; // ... for( std::list::iterator i = n.begin(); i != n.end(); ++i ) { if ( 0 > *i ) { n.erase( i ); } }
Halad´ o C++, 6/ 78
Iter´ator invalid´aci´o
std::list n; // ... for( std::list::iterator i = n.begin(); i != n.end(); ) { if ( 0 > *i ) { i = n.erase( i ); } else { ++i; } } Halad´ o C++, 7/ 78
Iter´ator invalid´aci´o
std::set s; // ... for( std::set::iterator i = s.begin(); i != s.end(); ) { if ( 0 > *i ) { s.erase( i++ ); // C++11: iterator-t ad vissza } else { ++i; } } Halad´ o C++, 8/ 78
vector reallok´aci´o
I
Elj´ar´as: u ´j mem´oriater¨ ulet allok´al´asa (´alt. k´etszeres kapacit´assal) elemek ´atm´asol´asa 3 r´ egi elemek megsz¨ untet´ese 4 r´ egi mem´oriater¨ ulet deallok´al´asa 1 2
I
k¨olts´eg, invalid iter´atorok
I
a kapacit´as nem cs¨okken automatikusan
Halad´ o C++, 9/ 78
vector::reserve
const int N = 1000; // reserve n´ elk¨ ul vector v; for(int i = 0; i < N; ++i) v.push_back( i ); // reserve-vel vector v; v.reserve( N ); for(int i = 0; i < N; ++i) v.push_back( i );
Halad´ o C++, 10/ 78
Kapacit´as cs¨okkent´ese
I
A vector ´es a string kapacit´asa nem cs¨okken automatikusan
I
Felesleges mem´oriafoglal´as
I
,,Swap-tr¨ ukk”: vector v; ... vector( v ).swap( v ); string s; ... string( s ).swap( s );
I
,,Minim´alis” kapacit´as
I
C++11: v.shrink to fit();
Halad´ o C++, 11/ 78
vector
I
teljes specializ´aci´o (Szabv´any)
I
nem bool-okat t´arol, t¨om¨orebb ´abr´azol´asm´od
I
Szabv´any szerint az operator[]-nak vissza kell adnia egy referenci´at az adott elemre
I
reference egy bels˝o proxy oszt´aly, szimul´alja a referenci´akat
Include-ok Bizonyos STL implement´aci´ok eset´en lefordul: #include //#include // ... vector v; int x; // ... vector::iterator i = find( v.begin(), v.end(), x ); I
Nincs defini´alva melyik fej´allom´any melyik m´asikat haszn´alja.
I
Hordozhat´os´agi probl´em´akat vet fel.
I
Hogyan ker¨ ulhet˝o el a hiba? Halad´ o C++, 14/ 78
Iter´atorok
I
container::iterator
I
container::const_iterator
I
container::reverse_iterator
I
container::const_reverse_iterator
I
istream_iterator, ostream_iterator
I
istreambuf_iterator, ostreambuf_iterator
I
inserter iter´atorok
Halad´ o C++, 15/ 78
Melyik iter´atort haszn´aljuk?
I
container::iterator: I
I I
iterator vector::insert( iterator position, const T& x); iterator vector::erase( iterator position ); iterator vector::erase( iterator first, iterator last );
Halad´ o C++, 16/ 78
Iter´atorok konverzi´oja
I
van iterator → const iterator konverzi´o
I
nincs const iterator → iterator konverzi´ o...
I
megold´asi lehet˝os´eg: typedef deque::iterator Iter; typedef deque::const_iterator ConstIter; deque d; ConstIter ci; ... Iter i = d.begin(); advance( i, distance( i, ci ) );
Probl´ema: hova mutat az az iterator, amit a base visszaad?
i = ri.base();
Halad´ o C++, 18/ 78
Iter´atorok konverzi´oja
I
J´o-e az az iterator, amit a base tagf¨ uggv´eny visszaad? I I
Besz´ ur´askor: OK T¨orl´eskor: NEM!
Container c; ... Container::reverse_iterator ri = ... // Ez nem minden esetben fordul le: c.erase( --ri.base() ); // Ez mindig j´ o: c.erase( (++ri).base() );
const int N = 10; double v[N]; ... double cv[N]; // v m´ asol´ asa cv-be: copy( v, v + N, cv ); // ez ´ altal´ aban nem m" uk¨ odik a val´ odi STL // kont´ enerek eset´ eben...
Halad´ o C++, 21/ 78
copy implement´aci´oja
template OutIt copy( InIt first, InIt last, OutIt dest ) { while ( first != last ) { *dest++ = *first++; } return dest; }
Halad´ o C++, 22/ 78
back inserter
double f( double x ) { ... } list<double> values; ... vector<double> results; results.reserve( values.size() ); // f-et alkalmazzuk values ¨ osszes elem´ ere, ´ es az // adatokat results v´ eg´ ere sz´ urjuk: transform( values.begin(), values.end(), back_inserter( results ), f ); Halad´ o C++, 23/ 78
front inserter
double f( double x ) { ... } list<double> values; ... list<double> results; // f-et alkalmazzuk values ¨ osszes elem´ ere, ´ es // az adatokat results elej´ ere sz´ urjuk: transform( values.begin(), values.end(), front_inserter( results ), f );
Halad´ o C++, 24/ 78
inserter double f( double x ) { ... } list<double> values; ... vector<double> results; results.reserve( values.size() ); // f-et alkalmazzuk values ¨ osszes elem´ ere, ´ es az // adatokat results k¨ ozep´ ere sz´ urjuk: transform( values.begin(), values.end(), inserter( results, results.begin() + results.size() / 2 ), f ); Halad´ o C++, 25/ 78
inserter
double f( double x ) { ... } list<double> values; ... multiset<double> results; // f-et alkalmazzuk values ¨ osszes elem´ ere, ´ es // az adatokat results-ba sz´ urjuk (rendezett lesz) transform( values.begin(), values.end(), inserter( results, results.begin() ), f );
Halad´ o C++, 26/ 78
back inserter implement´aci´oja (v´azlat) template class back_insert_iterator { Cont* c; public: explicit back_insert_iterator( Cont& cont ): c( &cont ) { } back_insert_iterator& operator++() { return *this; } back_insert_iterator& operator++( int ) { return *this; } Halad´ o C++, 27/ 78
back inserter implement´aci´oja (v´azlat)
back_insert_iterator& operator=( typename Cont::const_reference d ) // const typename Cont::value_type& d { c->push_back( d ); return *this; } back_insert_iterator& operator*() { return *this; } };
Halad´ o C++, 28/ 78
back inserter implement´aci´oja (v´azlat)
template back_insert_iterator back_inserter( Cont& c ) { return back_insert_iterator( c ); }
Halad´ o C++, 29/ 78
Funktorok
I
Olyan objektumok, amelyeknek van operator()-a – (glob´alis) f¨ uggv´enyh´ıv´asok szimul´al´asa
ezekre a typedef-ekre sz¨ uks´eg¨ uk van a f¨ uggv´enyobjektum adaptereknek (not1, not2, bind1st, bind2nd) unary function:
I
I I
I
argument type result type
binary function: I I I
first argument type second argument type result type
Halad´ o C++, 31/ 78
unary function, binary function
I
A unary function ´es a binary function sablon oszt´alyok
I
Sz´armaztatni p´eld´anyokb´ol kell
I
unary function: 2 sablon param´eter
I
binary function: 3 sablon param´eter
I
az utols´o param´eter mindig az operator() visszat´er´esi ´ert´eknek ,,megfelel˝o” t´ıpus
I
az els˝o param´eter(ek)nek az operator() param´etere(i)nek ,,megfelel˝o” t´ıpus(ok)
Halad´ o C++, 32/ 78
P´eld´ak struct IntGreater: binary_function { bool operator()( const int& a, const int& b ) const { return b < a; } }; struct CPtrLess: binary_function { bool operator()( const char* a, const char* b ) const { return strcmp( a, b ) < 0; } }; Halad´ o C++, 33/ 78
P´eld´ak class Sum: public unary_function { int partial_sum; public: Sum(): partial_sum( 0 ) { } void operator()( int i ) { partial_sum += i; } int get_sum() const { return partial_sum; } }; Halad´ o C++, 34/ 78
F¨uggv´enyek alkalmazkod´ok´epess´ege
I
f¨ uggv´enyek + adapterek? (pl. predik´atumf¨ uggv´eny neg´al´asa)
I
direktben nem megy, mert hi´anyoznak a typedef-ek...
I
ptr fun visszaad egy alkalmazkod´ok´epes funktort. Ennek az operator()-a megh´ıvja az eredeti f¨ uggv´enyt.
I
p´elda: bool is_even( int x ); // Els" o p´ aratlan sz´ am megkeres´ ese: list c; ... list::iterator i = find_if( c.begin(), c.end(), not1( ptr_fun( is_even ) ) ); Halad´ o C++, 35/ 78
mem fun, mem fun ref template Fun for_each( InputIter first, InputIter last, Fun f ) { while( first != last ) f( *first++ ); return f; } ... struct Foo { void bar(); }; list c; // bar megh´ ıv´ asa c ¨ osszes elem´ en? Halad´ o C++, 36/ 78