Vier Jahre vergingen, Google gab mir diese Antwort. Mit dem Standard C++11 (aka C++0x) gibt es tatsächlich eine neue angenehme Möglichkeit, dies zu tun (zum Preis der Rückwärtskompatibilität zu brechen): das neue auto
Schlüsselwort. Es erspart Ihnen die Qual, den Typ des Iterators explizit angeben zu müssen (den Vektortyp erneut wiederholen), wenn es offensichtlich ist (für den Compiler), welchen Typ zu verwenden. Mit v
als Ihrem vector
können Sie so etwas tun:
for ( auto i = v.begin(); i != v.end(); i++ ) {
std::cout << *i << std::endl;
}
C++11 geht sogar noch weiter und bietet Ihnen eine spezielle Syntax zum Iterieren über Sammlungen wie Vektoren. Es entfernt die Notwendigkeit, Dinge zu schreiben, die immer gleich sind:
for ( auto &i : v ) {
std::cout << i << std::endl;
}
Um dies in einem funktionierenden Programm zu sehen, erstellen Sie eine Datei auto.cpp
:
#include
#include
int main(void) {
std::vector v = std::vector();
v.push_back(17);
v.push_back(12);
v.push_back(23);
v.push_back(42);
for ( auto &i : v ) {
std::cout << i << std::endl;
}
return 0;
}
Zum Zeitpunkt des Verfassens dieses Textes müssen Sie dies beim Kompilieren mit g++ normalerweise angeben, um mit dem neuen Standard zu arbeiten, indem Sie eine zusätzliche Flagge angeben:
g++ -std=c++0x -o auto auto.cpp
Jetzt können Sie das Beispiel ausführen:
$ ./auto
17
12
23
42
Bitte beachten Sie, dass die Anweisungen zum Kompilieren und Ausführen spezifisch für den gnu c++ Compiler unter Linux sind, das Programm sollte plattformunabhängig sein (und Compiler-unabhängig).
11 Stimmen
Die ununterzeichnete ist korrekt, weil polygon.size() vom Typ unsigned ist. Unsigned bedeutet immer positiv oder 0. Das ist alles, was es bedeutet. Wenn die Variable immer nur für Zähler verwendet wird, dann ist unsigned die richtige Wahl.
0 Stimmen
Um die Warnung bezüglich signed/unsigned zu lösen, ersetzen Sie einfach
int
durchuint
(unsigned int
) bei der Deklaration voni
.3 Stimmen
@AdamBruss
.size()
ist nicht vom Typunsigned
a.k.a.unsigned int
. Es ist vom Typstd::size_t
.1 Stimmen
@underscore_d size_t ist ein Alias für unsigned.
5 Stimmen
@AdamBruss Nein.
std::size_t
ist ein implementationsdefiniertes Typedef. Siehe den Standard.std::size_t
könnte in Ihrer aktuellen Implementierung äquivalent zuunsigned
sein, aber das ist nicht relevant. Wenn man so tut, kann dies zu nicht-portablem Code und undefiniertem Verhalten führen.0 Stimmen
@underscore_d In welcher Version von C++ entspricht unsigned nicht size_t?
1 Stimmen
@underscore_d Ich lag falsch, als ich sagte, dass unsigned äquivalent zu size_t ist. size_t beträgt unter einer 64-Bit-Build 8 Bytes, wie du festgestellt hast. Dies gilt auch für Microsoft Visual C++. Aber wenn size_t tatsächlich zwischen zwei Compilern unterschiedlich wäre, wie du es sagst, dann hättest du nicht-portablen Code einfach durch die Verwendung von size_t.
0 Stimmen
@AdamBruss ...touché! Besiegt mit meiner eigenen Logik, macht meine Schimpftirade in meinem letzten Kommentar scheinheilig :-) Ja, implementierungsdefiniertes Verhalten scheint mit Typdefinitionen wie dieser garantiert zu sein, egal ob man sie verwendet oder ignoriert. Ich würde sagen, es ist wohl besser, sie zu verwenden, wenn verfügbar, auch wenn der Nutzen rein theoretischer Natur ist - aber im Gegensatz dazu stehen andere Diskussionen, bei denen Leute argumentieren, dass
std::size_t
weitgehend sinnlos ist und alle normalen Schleifen mitint
durchgeführt werden sollten! Ich glaube, das sind keine wirklich praktischen Themen, da nur wenige Menschen jemals solch große Arrays verwenden werden.0 Stimmen
@underscore_d Ich denke, dass size_t eine notwendiges Übel ist, um eine size()-Funktion zu ermöglichen, die beispielsweise anstelle einer Funktion zurückgeben kann, die ein 4-Byte-unsigned und eine Funktion zurückgeben kann, die ein 8-Byte-unsigned zurückgibt. Ich stimme dem großen Containers zu.
1 Stimmen
@underscore_d Es handelt sich nicht um den Typ
size_t
, sondern um den Typdecltype(polygon)::size_type
.