Waarom is er geen pop_front methode in C++ std::vector?

Waarom is er geen pop_frontmethode in C++ std::vector?


Antwoord 1, autoriteit 100%

Omdat een std::vectorgeen specifieke functie heeft met betrekking tot het invoegen van elementen aan de voorkant, in tegenstelling tot sommige andere containers. De functionaliteit van elke container is logisch voor die container.

U zou waarschijnlijk een std::dequemoeten gebruiken, die expliciet goedis bij het invoegen aan de voor- enachterkant.

Bekijk dit diagramuit.


Antwoord 2, autoriteit 48%

Hoewel inefficiënt voor grote vectoren, is het volgende equivalent aan een pop_front()voor een std::vector

vec.erase(vec.begin());

Zoals vermeld in andere antwoorden, is std::vectorniet ontworpen om het eerste element te verwijderen en zal het nodig zijn om alle resterende elementen te verplaatsen/kopiëren. Afhankelijk van het specifieke gebruik, kan het handig zijn om andere containers te overwegen.


Antwoord 3, autoriteit 26%

vector wordt meestal als volgt geïmplementeerd:

struct 
{
  T* begin; // points to the first T in the vector
  T* end; // points just after the last T in the vector
  int capacity; // how many Ts of memory were allocated
};

“begin” heeft een dubbele functie als “aanwijzer naar de eerste T in de vector” en “aanwijzer naar al het geheugen dat we hebben toegewezen.” daarom is het onmogelijk om elementen van de voorkant van de vector te “poppen” door simpelweg “begin” te verhogen – doe dit en je hebt niet langer een verwijzing naar het geheugen dat je nodig hebt om de toewijzing ongedaan te maken. dat zou geheugen lekken. dus een “pop_front” zou alle T’s van de achterkant van de vector naar de voorkant van de vector moeten kopiëren, en dat is relatief langzaam. dus besloten ze het uit de standaard te laten.

wat je wilt is zoiets als dit:

struct 
{
  T* allocated; // points to all the memory we allocated
  T* begin; // points to the first T in the vector
  T* end; // points just after the last T in the vector
  int capacity; // how many Ts of memory were allocated
};

Hiermee kun je “pop_front” door “begin” naar voren en naar achteren te bewegen zonder het gevaar te vergeten welk geheugen je later moet vrijgeven. waarom werkt std::vector niet op deze manier? ik denk dat het een kwestie van smaak was onder degenen die de standaard schreven. hun doel was waarschijnlijk om de eenvoudigst mogelijke “dynamisch aanpasbare array” te bieden die ze konden, en ik denk dat ze daarin zijn geslaagd.


Antwoord 4, autoriteit 16%

Omdat push_backen pop_backspeciale bewerkingen zijn voor een vector waarvoor alleen O(1)berekeningen nodig zijn. Elke andere push of pop kost O(n).

Dit is geen “bug” of “quirk”, dit is slechts een eigenschap van de vectorcontainer. Als je een snelle pop_front nodig hebt, overweeg dan om over te stappen op een andere container.


Antwoord 5, autoriteit 5%

Als je echter een pop_front nodig hebt en niet geeft om de index van de elementenin de vector, kun je een soortpop_front maken met zoiets als

template<typename T>
void pop_front(std::vector<T>& vec)
{
   vec.front() = vec.back();
   vec.pop_back();
}

Dan Higgins heeft dit ook over: https://youtu.be/obbgc-suyva?t = 2m52s


6, Autoriteit 2%

Waarschijnlijk omdat het monumentaal traag zou zijn voor grote vectoren.

pop_front()op een vector met 1000 objecten zou 999 vereisen operator=()oproepen.


7

#define push_front(v,val) v.insert(v.begin(), 1, val);
#define pop_front(v)  if(!v.empty())v.erase(v.begin());

U kunt dit direct schrijven en dit gebruiken

push_front(vec,val);
pop_front(vec);

Other episodes