pointer und std::vector problem



  • hola leute

    gezwungenermassen muss ich mich auf den VC++ 2005 umgewoehnen und hab da mit meinen bisherigen sources leichte probleme mit z.b. dem std::vector.

    ich hab bei mir oeffters folgendes stehen:

    std::vector<uint8> vec;
    ...
    uint8 *it = vec.begin(); // hier liegt das problem
    

    warum kann ich ne addresse von einem uint8 nicht einem uint8* zuweissen ?
    is das ne doofe eigenheit von VC ?
    begin() muesste mir doch die adresse des ersten elements zurueckgeben. oder etwa nicht ?

    Meep Meep



  • Ehm, normalerweise bekommst du einen Iterator und keinen Pointer zurück. Klar, der Iterator selbst wird vom User wie ein Pointer gehandhabt, aber es ist trotzdem ein komplexer Typ.

    std::vector<unit8>::iterator it = vec.begin();
    

    Aber war es jemals anders? 😃

    Da es bisher niemals anders war (außer die Std-Lib oder Compiler haben es anders gesehen) gibts im nächsten C++Standard das hier, damit man nicht soviel tippen muß:

    auto it = vec.begin();
    

    Aber als Übergang würde ich dir raten das hier zu machen, um Tiparbeit zu sparen:

    typedef std::vector<unit8> uint8Vec;
    
    uint8Vec vec;
    uint8Vec::iterator it = vec.begin();
    


  • hoi artchi

    naja das problem is halt das ich jetz ziemlich viel aendern muesste.
    mit dem BCB hat es da nie probleme gegeben. auch mit dem GCC hat es glaub ich immer geklappt.
    heisst es nicht im std das der vector einen zusammenhaengenden buffer verwalten soll/muss ? bin dadurch davon ausgegangen das man dann immer einen normalen pointer zurueck bekommt. oder hab ich mich da vertan ?

    Meep Meep



  • Ja, der BCB ist dafür bekannt den C++ Standard schlecht zu unterstützen. Selbst der neue 2006er von Borland ist noch schlecht. Die IDE mag gut sein, aber nicht was den ISO-Standard angeht. GCC war auch seeehr lange schlecht bzgl. Standard, da hat sich glaub ich auch erst richtig was mit der 4er Version getan. Also, das es da funktioniert hat, hat nicht viel zu bedeuten.

    Dir bleibt leider nichts übrigen als jetzt alles anzupassen. Denn das ein Iterator zurück gegeben wird, ist einfach der ISO-Standard. Der Sinn ist einfach, das die Daten im Vector zwar (wir von dir richtig vermutet) auch über einen Pointer angesprochen werden können, aber ein roher Pointer ist halt "dumm". Ein Iterator bewirkt eine Kapselung, die einfach wartbarer ist. Bsp.:

    typedef std::vector<unit8> uint8Vec;
    
    uint8Vec vec;
    uint8Vec::iterator it = vec.begin();
    

    Irgendwann fällt dir auf: "Huch, ich muß jetzt auf eine List umsteigen." Oder "ich will jetzt keine uint8s mehr, sondern longs drin haben." Dann kannst du das hier machen:

    typedef std::list<unit8> uint8Vec; // list anstatt vector
    
    uint8Vec vec;
    uint8Vec::iterator it = vec.begin(); // funktioniert noch!
    

    oder

    typedef std::vector<long> uint8Vec;  // longs
    
    uint8Vec vec;
    uint8Vec::iterator it = vec.begin(); // funktioniert noch!
    

    Bei einem rohen Pointer müsstest du wie jetzt deinen Code an mehreren Stellen bearbeiten. Aber so, ist der Iterator einfach schlauer und du benutzt ihn trotzdem wie einen Pointer.

    Da (zum Glück) alle neuen guten Compiler den Standard unterstützen, wirst du die Arbeit einfach machen müssen. Weil sonst schiebst du deinen illegalen Code nur vor dir her. So mühselig sich das leider anhört.


Anmelden zum Antworten