Container an Funktionen übegeben



  • Nabend leute,

    ich tue mich momentan mit dem STL-Einstig etwas schwer. wie der Name schon sagt: es gelingt mir nicht eine Container (nehmen wir mal vector<int>) an eine Templatefunktion zu übergeben, die dann einen Iterator von vector<int> erstellt und den vector einmal durchläuft (z.B. zur Ausgabe) - sowas ist doch möglich oder nicht? Ausserdem verstehe ich auch die typedefs wie z.B. const_pointer, value_type etc. nicht so ganz. Also ich weiss schon was sie bedeuten aber wäre nett wenn mir das nochmal kurz wer erklären könnte. Und noch eins: gibt es in C++ eine Art "divison by zero"-exception? Wenn ja, wie lautet diese dann exakt?

    bisschen viel auf einmal deshalb schonmal besten dank für euere bemühungen im voraus 😉 .



  • Anfänger_braucht_hilfe schrieb:

    ich tue mich momentan mit dem STL-Einstig etwas schwer. wie der Name schon sagt: es gelingt mir nicht eine Container (nehmen wir mal vector<int>) an eine Templatefunktion zu übergeben, die dann einen Iterator von vector<int> erstellt und den vector einmal durchläuft (z.B. zur Ausgabe) - sowas ist doch möglich oder nicht?

    Normalerweise sollte das gehen. Zeig doch mal, was du versucht hast, dann können wir dir erklären, wo dein Fehler liegt.

    Ausserdem verstehe ich auch die typedefs wie z.B. const_pointer, value_type etc. nicht so ganz. Also ich weiss schon was sie bedeuten aber wäre nett wenn mir das nochmal kurz wer erklären könnte.

    Diese Typedef's sind praktisch für die Template-Programmierung - damit kannst du innerhalb einer Template-Funktion (z.B.) Iteratoren oder Hilfsvariablen definieren, deren Typ zum übergebenen Container passt.

    Und noch eins: gibt es in C++ eine Art "divison by zero"-exception? Wenn ja, wie lautet diese dann exakt?

    Afaik nein - "division by zero" wird von der ALU abgefangen und endet bestenfalls in einem Signal.



  • @ CStoll: Vielen Dank erstmal für die Erklärung, das mit der Template Funtkion hab ich selbst hinbekommen aber erst nachdem mich der Compiler darauf hingewiesen hat, dass vor

    T::const_iterator itr;
    

    noch ein

    typename
    

    fehlt, was ich bis dato noch nicht kannte.

    Jetzt verstehe ich immer noch nicht:

    1. Wozu dient das typename und warum braucht man das da?

    2. Wenn ich nur die Iteratoren an eine Funktion übergebe, wie kann ich dann feststellen (bzw. können die STL-Algorithmen feststellen) ob die Iteratoren auch vom gleichen Containertyp oder vom gleichen Containerobjekt sind. Wenn man z.B. schreibt

    set_difference(vec1.begin(), vec2.begin(), vec3.begin(), vec4.begin(), vec_res.begin()
    

    schliesst sich das Programm, bei anderen Algorithmen wird stattdessen (soweit jedenfalls meine Erfahrung) der Vector vec_res nur nicht verändert.

    3. (code siehe 2) In wie weit sind die STL-Containerklassen gegen Speicherüberschreitung abgesichert? Wenn die ersten 4 Prameter der oberen Funktion korrekt wären und die Menge 10 Elemente hätte, vec_res jedoch nur Speicher für 5, dann werden auch immer nur die ersten 5 gespeichert. Wenn allerdings zuvor kein Speicher reserviert wurde dann bricht das Programm mit einer Fehlermeldung ab (... an Microsoft senden ...). Bei mir typisch für Speicherüberschreitung deshlab habe ich auch das Gefühl dass bei 5 Elementen trotzdem mehr in den Speicher geschrieben wird, weiss aber nicht ob das stimmt.



  • 1. typename gibt dem Compiler an, dass es sich um einen Typ handelt. Er braucht das dann, wenn der Template Parameter ( hier T ) noch nicht aufgelöst ist. (In Wahrhheit ist es glaub ich noch komplizierter, aber das sollen dir die Provis erklären)

    2. Schau dir die Signatur an

    template <class InputIterator1, class InputIterator2, class OutputIterator>
    OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
                                  InputIterator2 first2, InputIterator2 last2,
                                  OutputIterator result);
    

    Das ist ein Template, logisch, und die Iteratoren können hier durchaus unterschiedliche Typen haben, im ganzen drei verschiedene. Wie der Algo intern mit verschiedenen Typen klar kommt, kannst du in den Headern (hier wohl <algorithm> ) nachsehen.

    3. Normalerweise wird ein vector<T> verdoppelt, wenn er voll ist. Da der Algo hier aber mit anderen Containern und auch C-Arrays funktionieren soll, sind Bedingungen gegeben

    Preconditions
    For the first version:

    * [first1, last1) is a valid range.
    * [first2, last2) is a valid range.
    * [first1, last1) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, *j < *i is false.
    * [first2, last2) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, *j < *i is false.

    • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + n) is a valid range, where n is the number of elements in the difference of the two input ranges.
      * [first1, last1) and [result, result + n) do not overlap.
      * [first2, last2) and [result, result + n) do not overlap.

    Quelle: http://www.sgi.com/tech/stl/set_difference.html



  • Ok vielen Dank!

    Aber ...

    2: Hier sind ja vermutlich Fallunterscheidungen oder ähnliches erforderlich, aber wie komm ich da ran. Sowas findet man doch nicht im Header.

    3: Hier ist man dann also selbst verantwortlich, dass diese Bedingungen erfüllt werden (v.a. die von dir hervorgehobene Bedingung) und falls nicht hat man ein Problem das unbemerkt weiterläuft oder wie?



  • Anfänger_braucht _hilfe schrieb:

    2: Hier sind ja vermutlich Fallunterscheidungen oder ähnliches erforderlich, aber wie komm ich da ran. Sowas findet man doch nicht im Header.

    Nein, Du knüpfst normalerweise Bedingungen an die Form der Iteratoren. Z.B. alle Input-Iteratoren müssen Vorwärts-Iteratoren sein, also einen operator++ besitzen. Ist das nicht der Fall wird Dir der Compiler das i.A. bei Verwendung des Templates mitteilen.

    3: Hier ist man dann also selbst verantwortlich, dass diese Bedingungen erfüllt werden (v.a. die von dir hervorgehobene Bedingung) und falls nicht hat man ein Problem das unbemerkt weiterläuft oder wie?

    Exakt. Genauergesagt ruft die Nichteinhaltung der Bedingungen undefiniertes Verhalten hervor. Sprich wenn Du Glück hast kracht es sofort, wenn Du Pech hast schreibts Dir irgendwelchen Speicher kaputt und das Programm benimmt sich danach völlig daneben.



  • ok Danke nochmals ich denke jetzt hab ich alles verstanden ;).


Log in to reply