Angenommen, ich habe eine Containerklasse Box
, die die inneren Klassen const_iterator
und iterator
enthält. Weil ich möchte, dass ein iterator
zu einem const_iterator
castbar ist, erbt letzterer vom ersteren:
Nun möchte ich diese Klassen mit Google Test testen. Lassen Sie uns behaupten, dass die begin()
und end()
nicht die gleiche Sache zurückgeben:
Sag Hallo zu einem Kompilierfehler:
no member named 'begin' in 'Box::const_iterator'
‘const class Box::const_iterator’ has no member named ‘begin’
Einige Recherchen haben mich zu dieser Vorlage geführt im Google Test-Quellcode (folgen Sie dem Link für die erweiterte Dokumentation):
%Vor% Das Ergebnis dieser Template-Magie ist, dass, wenn Argumente für EXPECT_*
die Klassen iterator
und const_iterator
Member haben, der Typ als eine Container-Klasse angenommen wird. Google Test kann so gut lesbare Berichte erstellen, wenn die Erwartungen nicht erfüllt werden. Das ist nett.
Allerdings gibt es dieses kleine Detail:
%Vor%Wenn ich die Dinge richtig verstehe, bedeutet das,
Box::const_iterator
hat sich selbst als Mitgliedsklasse mit dem Namen const_iterator
und std::iterator
als Mitgliedsklasse mit dem Namen iterator
. Box::iterator
hat sich selbst als Mitgliedsklasse mit dem Namen iterator
und Box::const_iterator
als Mitgliedsklasse namens const_iterator
. Daher sehen beide Iterator-Klassen wie Container-Klassen für Google Test aus!
Wie gestalte ich meine Iterator-Klassen so, dass sie nicht wie Container aussehen?
Dinge, die ich versucht habe:
std::iterator
von const_iterator
als private
. Das behebt das Problem für const_iterator
, indem die iterator
-Memberklasse ausgeblendet wird, aber es lässt mich weiterhin nicht a.begin()
als Parameter an EXPECT_NE
übergeben, außer a
ist const
. Es scheint, als ob Google Test iterator begin()
anstatt const_iterator begin() const
aus irgendeinem Grund verwendet. std::iterator
insgesamt. Ist das eine schlechte Idee? Ich nehme an, dass ich meine std::iterator_traits
manuell deklarieren muss. Gibt es sonst noch etwas, das ich verliere, wenn ich std::iterator
nicht erweitere? Box::const_iterator
von Box::iterator
als private
. Dies kann oder kann keine Option sein, da ich Methoden neu deklarieren müsste, die ich lieber wiederverwenden möchte (z. B. operator++
). Gibt es noch etwas, was ich übersehen habe?
ThreeInts::iterator
sollte nicht von ThreeInts::const_iterator
erben, stattdessen sollten sie separat implementiert werden.
Das Problem scheint zu sein, dass sonst ThreeInts::const_iterator
beide Mitglieder namens const_iterator
und iterator
(aka die Konstruktoren) haben. Das iterator
von const_iterator
zu erben ist auch nicht const-korrekt, da const_iterator
nur einen Zeiger / ähnlich zu const
data enthalten sollte. STL-Container halten auch die beiden Iteratoren getrennt.
In diesem Code würde es wahrscheinlich ausreichen, statt Iteratorklassen zu definieren, einfach
zu definieren %Vor%Tags und Links c++ c++11 templates googletest