Chcę mieć pewnego rodzaju std::vector
, który nie może mieć więcej niż const int MAX_LENGTH
elementów. Rozumiem, że nie mogę przesłonić innych niż wirtualne funkcji, które musiałbym wykonać, aby umieścić kontrolę rozmiaru we wszystkich odpowiednich funkcjach składowych (np. assign
, push_back
... jest ich tak wiele). Najbardziej oczywistym sposobem na zrobienie tego jest owijanie std::vector
w class
, który zapewnia, że żadna operacja nie zostanie przedłużona poza maksymalną długość. Ale wydaje się to nieporęczne. Czy istnieje bardziej eleganckie rozwiązanie niż klasa opakowania w celu ograniczenia rozmiarów std :: vector?Niewpuszczalny sposób na wymuszenie ograniczenia rozmiaru na std :: vector?
Odpowiedz
Czy jesteś pewien, że sam wektor nie może się rozwinąć, lub że tylko konsumenci takiego wektora muszą ograniczyć rozmiar argumentów? Jeśli to drugie, to po prostu assert(arg.size() <= MAX_LENGTH)
w razie potrzeby, udokumentuj to i gotowe. W przeciwnym razie czytaj dalej.
A std::vector
może mieć nieograniczony rozmiar. Jeśli ograniczysz ten rozmiar, to już nie jest to std::vector
. Więc nie możesz publicznie czerpać z std::vector
i ograniczać rozmiaru bez łamania Liskov Substitution Principle. Klasa pochodna nadal jest wektorem, ale nie działa tak jak jeden i nie może być używana jako jedna, a taki interfejs całkowicie zmyli użytkowników, a kompilator nie wykryje poważnych błędów użytkowania. To zły pomysł.
Najlepsze, co można zrobić, to prywatnie czerpać z wektora lub mieć wektor jako element członkowski i odsłonić wszystkie interfejsy wektorowe, jednocześnie wymuszając rozmiar. Taki wektor musi być , a nie być zamienny na std::vector
, chociaż oczywiście można zezwolić na jego skopiowanie lub przeniesienie do std::vector
. Nadal będzie działał tak dobrze, jak wektor będzie nadal pozwalał na dostęp poprzez iteratory, itp.
Mówimy o bardzo małej klasie, a jej implementacja musi po prostu być zgodna ze standardem (lub przynajmniej the cpp reference), pozostawiasz całą prawdziwą pracę prywatnemu std::vector
. Więc to nie jest przyziemne, to jedyny rozsądny sposób, aby to zrobić.
Rozumiem twój punkt widzenia. Podoba mi się ten pomysł assert (arg.size() <= MAX_LENGTH), ale gdzie by to poszło, gdyby nie niestandardowa klasa opakowania? Nie mogę zmusić klientów do umieszczania ich przed każdym telefonem, więc czy istnieje sposób, aby to zrobić automatycznie? – helloB
Nie używałbyś assert, gdybyś chciał podnieść konkretny wyjątek, użyłbyś go do zawieszenia programu, ponieważ popełniłeś błąd –
@helloB Klienci definitywnie mogą je umieścić, jeśli naprawdę nie mogą zaakceptować wektora za duży. Po to są twierdzenia. W przeciwnym razie wydaje się, że masz problem. Wektor nie dba o jego rozmiar, teraz klienci też go nie interesują, więc dlaczego pytanie? Jeśli klienci się tym przejmują, muszą sprawdzić lub zaakceptować ograniczoną wielkość klasy wektorowej, a nie "std :: vector". Jeśli klienci nie przejmują się, dlaczego? –
Od C++ 11, niestandardowe alokatory mogą mieć stan (poprzednio w C++ 11, niestandardowe alokatory musiały być bezstanowe). Każdy kontener C++, który pobiera niestandardowy alokator, przechowuje jego instancję.
Twój alokator może następnie sprawdzić, czy już wypełnił żądanie maksymalnego przydziału i rzucić coś innego.
Działa to tylko wtedy, gdy posiadam indywidualną instancję przydzielania dla każdego wektora nr? Albo musiałbym mieć dość dużo zarejestrowanego stanu w alokatorze, śledząc każdy wektor, który mu przydzielił. – helloB
@helloB: Tak. Każdy wektor ma własną instancję alokatora (drugie zdanie pierwszego akapitu). – jxh
To niekoniecznie musi być. Widziałem podzielniki podzielone między kontenerami. – helloB
#include <vector>
#include <string>
using namespace std;
template <typename T, typename A>
void add_or_throw(std::vector<T,A> &vec, int max, T value)
{
if (vec.size() < max)
{
vec.push_back(value);
}else{
throw length_error("vecor too beaucoup");
}
}
int main() {
std::vector<std::string> v;
add_or_throw(v, 2, string("hi"));
add_or_throw(v, 2, string("there"));
add_or_throw(v, 2, string("man!"));
return 0;
}
- 1. Czy std :: vector be ='d na inny std :: vector?
- 2. Konwersja std :: array na std :: vector
- 3. Obiekt zorientowany na sposób iteracji poprzez std :: vector?
- 4. std :: vector na przód zadeklarowanego typu
- 5. Jak wycinać `std :: vector` na podstawie elementów w` std :: set`
- 6. std :: vector std :: wektory sąsiedztwo
- 7. Jakie jest uzasadnienie projektu metody zmiany rozmiaru std :: vector?
- 8. posix_memalign dla std :: vector
- 9. Prawidłowy sposób przeniesienia własności std :: vector <std :: unique_ptr < int>> na konstruowaną klasę
- 10. sizeof() std :: vector (C++)
- 11. Czy mogę rzucić std :: vector <Animal*> na std :: vector <Dog*> bez patrzenia na każdy element?
- 12. Eigen i std :: vector
- 13. std :: vector odniesień
- 14. C++ w std :: vector
- 15. Najprostszy sposób na wymuszenie awarii w Swift
- 16. Wymień `std :: vector` z` std :: array`
- 17. Zwracanie std :: vector - right approach
- 18. C++ Przekształć std :: tuple <A, A, A...> na std :: vector lub std :: deque
- 19. Dlaczego interfejs konstruktora std :: vector został zmieniony na C++ 11?
- 20. Jak przekonwertować std :: vector <uint8_t> na QByteArray?
- 21. Czy istnieje sposób na wymuszenie formatu pliku README.txt na github?
- 22. std :: vector i std :: min zachowanie
- 23. std :: copy i std :: vector problemem
- 24. Dziedziczenie ze standardu std :: vector
- 25. Odpowiednik std :: vector w Javie?
- 26. Adres std :: vector sam stable?
- 27. kopiowania std :: vector do qvector
- 28. Względna wydajność std :: vector vs. std :: list vs. std :: slist?
- 29. Rozszerzenie aplikacji na ograniczenia iOS8
- 30. Skąd wektor std :: vector przydziela jego pamięć?
@LuchianGrigore Nie, potrzebuję interfejsu wektorowego lub wektorowego. – helloB
Jakiego zachowania oczekujesz, jeśli zostanie naruszone? Jeśli wektor ma taką pojemność, co powinien zrobić 'push_back' (lub equiv)? Zgłaszać wyjątek? Cicho odrzucić ten element? Dodaj ten element kosztem pierwszego elementu (zachowanie typu kolejki FIFO)? – CoryKramer
@CoryKramer Chciałbym rzucić wyjątek i przypomnieć użytkownikowi, że złamali warunki używania tego konkretnego rodzaju wektora (wektor jest tym, który używa określonego przydziału) – helloB