Portál AbcLinuxu, 14. května 2025 17:00

Dotaz: Konverze iterátorů

27.4.2009 19:22 Andrej | skóre: 51 | blog: Republic of Mordor
Konverze iterátorů
Přečteno: 261×
Odpovědět | Admin

Ahoj, dnes jsem narazil na cosi zvláštního. Změnil jsem typ STL kontejneru a nepoužil jsem refactoring. Eclipse tedy přeložil projekt s původními deklaracemi iterátorů a s novým typem kontejneru. Kupodivu bylo možné (aspoň z pohledu překladače a v době překladu) přiřadit nekompatibilní iterátory.

Deklarace kontejneru:

    const std::map< uint32_t, Hook * > hooks; 

Tohle se nepřeloží a důkladně to zařve, což jistě nikoho nepřekvapí:

    const std::vector< Hook * >::const_iterator end = hooks.end();

Jenže (a teď to přijde!) tohle se mi přeloží:

    const std::vector< Hook * >::const_reverse_iterator end = hooks.rend();

Jak to? Proč? Kdyby konverze těch iterátorů dávala smysl (iterace přes klíče...?), byl by na to konverzní operátor a bylo by to v dokumentaci. (Navíc by to fungovalo v obou směrech.) Jenže pokud vím, není tomu tak. Ještě doplním, že používám kompilátor Intel.

Tohle je buď záhada, nebo další tajemné zákoutí C++, které ještě neznám. Je snad mezi „normálními“ a „převrácenými“ iterátory nějaký podstatný rozdíl?

Nástroje: Začni sledovat (3) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

Voty avatar 28.4.2009 08:53 Voty | skóre: 12 | blog: gemini
Rozbalit Rozbalit vše Re: Konverze iterátorů
Odpovědět | | Sbalit | Link | Blokovat | Admin

Zajímavé, zajímavé. gcc to vezme také, a dokonce je spokojený i s tímhle :(

    const std::map< std::string, std::string > hooks;
    const std::vector< int ** >::const_reverse_iterator end = hooks.rend();

 

Jednu rozbil a tu druhou ztratil.
28.4.2009 14:20 Sinuhet | skóre: 31
Rozbalit Rozbalit vše Re: Konverze iterátorů
Odpovědět | | Sbalit | Link | Blokovat | Admin

Jak vypada vas zdrojak? Jak ho kompilujete? Mne to g++ (verze 3.3, 4.[0-3]) nesezere.

$ cat test.cc

#include <vector>
#include <stdint.h>
#include <map>

struct Hook
{
        char data;
};

int main(int argc, char** argv)
{
        const std::map<uint32_t, Hook*> hooks;

//      const std::vector< Hook * >::const_iterator end_a = hooks.end();
        const std::vector< Hook * >::const_reverse_iterator end_b = hooks.rend();

        return 0;
}

$ g++ -o test test.cc
/usr/include/c++/4.3/bits/stl_iterator.h: In constructor ‘std::reverse_iterator<_Iterator>::reverse_iterator(const std::reverse_iterator<_Iter>&) [with _Iter = std::_Rb_tree_const_iterator<std::pair<const unsigned int, Hook*> >, _Iterator = __gnu_cxx::__normal_iterator<Hook* const*, std::vector<Hook*, std::allocator<Hook*> > >]’:
test.cc:16:   instantiated from here
/usr/include/c++/4.3/bits/stl_iterator.h:139: error: no matching function for call to ‘__gnu_cxx::__normal_iterator<Hook* const*, std::vector<Hook*, std::allocator<Hook*> > >::__normal_iterator(std::_Rb_tree_const_iterator<std::pair<const unsigned int, Hook*> >)’
/usr/include/c++/4.3/bits/stl_iterator.h:683: note: candidates are: __gnu_cxx::__normal_iterator<_Iterator, _Container>::__normal_iterator(const _Iterator&) [with _Iterator = Hook* const*, _Container = std::vector<Hook*, std::allocator<Hook*> >]
/usr/include/c++/4.3/bits/stl_iterator.h:680: note:                 __gnu_cxx::__normal_iterator<_Iterator, _Container>::__normal_iterator() [with _Iterator = Hook* const*, _Container = std::vector<Hook*, std::allocator<Hook*> >]
/usr/include/c++/4.3/bits/stl_iterator.h:666: note:                 __gnu_cxx::__normal_iterator<Hook* const*, std::vector<Hook*, std::allocator<Hook*> > >::__normal_iterator(const __gnu_cxx::__normal_iterator<Hook* const*, std::vector<Hook*, std::allocator<Hook*> > >&)

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.