2016-07-01 14 views
1

Soweit ich weiß, hat Stack in C++ keine Iteratoren. In diesem Post (Does std::stack expose iterators?) wird beispielsweise explizit angegeben, dass der Stapel keine Iteratoren aufweist. Allerdings wurde mir von meinem Vorgesetzten gesagt, dass Stack in C++ Iteratoren haben sollte, da es sich um eine Standard-Datenstruktur handelt, und Sie können stack.begin() ausführen (von dem, was ich weiß, gibt es im Standard C++ keine solche Syntax). Wie überzeuge ich ihn? Warum hat der Stapel keine Iteratoren in C++?Hat Stack Iteratoren in C++?

Frage # 2: Danke euch allen für tolle Antworten. Ich denke, die Frage kommt nun auf: Warum macht es keinen Sinn, Iteratoren für den Stack zu haben?

+0

Werfen Sie einen Blick auf die Dokumentation ... http: //www.cplusplus.com/reference/stack/stack/ Gibt es einen Iterator? Nopp. Start() ? Nopp. – SnoozeTime

Antwort

6

Sie können Ihren Vorgesetzten davon überzeugen, indem Sie Ihren Vorgesetzten informieren und Abschnitt 23.6.5 von ISO/IEC-14882 (2011), die Spezifikation für std::stack, lesen.

std::stack hat keine Iteratoren.

+0

Er könnte auch dem Vorgesetzten gegenüber erwähnen, dass die Funktionalität der STL im Allgemeinen super-pünklich spezifiziert ist (wie diese Antwort "Zitat" andeutet), und so wie sich ein Teil davon verhalten sollte, ist im Gegensatz zu MarkDown oder PHP von eigensinnig befreit Subjektivität. – fish2000

3

std::stack bietet eine streng letzte Ansicht des zugrunde liegenden Containers, und das ist der Sinn: die Verwendung des zugrunde liegenden Containers auf LIFO zu beschränken.

Und so bietet es keine Iteration.

Allerdings bietet es den zugrunde liegenden Container als protected Mitglied, was bedeutet, dass es für abgeleitet werden soll. In Ihrer abgeleiteten Klasse können Sie Iteratoren und was immer Sie wollen bereitstellen. Es ist auch möglich, einfach auf das protected Mitglied eines gewöhnlichen std::stack zuzugreifen, auch ohne irgendeine Umwandlung zu verwenden (nämlich durch implizite Umwandlung von Mitgliedsdatenzeiger).

Re die zusätzlichen 2 nd Frage,

, warum es keinen Sinn macht Iteratoren für Stapel zu haben?

Es kann sinnvoll sein, aber in den meisten Fällen wäre es den nicht-LIFO-Zugang zur Verfügung stellt, dass std::stack ausgelegt ist, zu entfernen, das heißt in den meisten Fällen im Widerspruch zu dem Zweck der std::stack wäre.

Zum Debuggen zeigt der Debugger den Inhalt einer std::stack, so dass es keine große Notwendigkeit gibt, direkte Unterstützung dafür in Code zu haben.


Beispiel:

#include <iostream> 
#include <stack> 

namespace cppx { 
    using std::stack; 

    namespace hack { 
     template< class Item > 
     auto container_of(stack<Item> const& st) 
      -> typename stack<Item>::container_type const& 
     { 
      struct Hacked: stack<Item> { using stack<Item>::c; }; 
      return st.*&Hacked::c; 
     } 
    } // namespace hack 

    template< class Item > 
    auto begin(stack<Item> const& st) 
    { return hack::container_of(st).begin(); } 

    template< class Item > 
    auto end(stack<Item> const& st) 
    { return hack::container_of(st).end(); } 

} // namespace cppx  

auto main() 
    -> int 
{ 
    using namespace std; 

    stack<int> st; 
    for(int const x : {3, 1, 4, 1, 5, 9, 2, 6, 5, 4}) 
    { 
     st.push(x); 
    } 

    using cppx::begin; using cppx::end; 
    for(auto it = begin(st); it != end(st); ++it) 
    { 
     cout << *it << " "; 
    } 
    cout << endl; 
} 

Da in diesem Beispiel begin und end im Namensraum nicht platziert sind std ein Bereich basierend Schleife würde nicht kompiliert.

Ich habe das nicht getan, weil die Legalität (Gültigkeit) der Spezialisierung einer Standardfunktion für einen Standardcontainer, in Namespace std, ein Problem ist, das ich hier nicht eingehen möchte. Ich denke, es ist nicht erlaubt, obwohl die Spezialisierung auf den eigenen Typ in Ordnung wäre. Aber ich bin mir nicht sicher.

+0

Geht das immer nach Standard? Ich dachte, STL-Container seien nicht für Unterklassen bestimmt. – bipll

+1

@bipll: Ja, der Standard erfordert das geschützte Mitglied. Und nein, es ist nicht wahr, dass STL-Container nicht darauf ausgelegt sind, abgeleitet zu werden. 'std :: stack' ist das Hauptgegenbeispiel. –

+0

@ Cheersandhth.-Alf wissen Sie zufällig, warum der Begriff "nicht von STL-Containern herrühren" so stark vertreten ist - gibt es tatsächlich Fallstricke in der Praxis? – fish2000

1

std::stack ist aber ein Container-Adapter.Es akzeptiert standardmäßig einen Containertyp (std::deque) als Vorlageparameter, und eine Instanz von stack kann aus einer Instanz dieses Containers erstellt werden, ansonsten wird der zugrunde liegende private Container jedoch nicht angezeigt und der Stack selbst verfügt nicht über Iterationsfunktionen.