 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Michael Trocken Guest
|
Posted: Sat Nov 29, 2003 2:15 pm Post subject: vector auf dem Stack |
|
|
Um schnelle Operationen auf dem Stack mit der Flexibilität von
»vector« zu verbinden, habe ich einen Container »fastvector«
(Beispiel-Quelltext s.u.) geschrieben, der die ersten Elemente auf dem
Stack anlegt (entsprechende Deklaration des Containers vorausgesetzt)
und erst ab einer bestimmten Anzahl von Elementen auf den Heap
ausweicht.
Was müsste man bei einer allgemeinen Verwendung ggf. beachten? Ein
Problem dürfte beispielsweise sein, dass bei sehr großen Typen T der
Stack zu stark belastet wird, was sich aber wiederum durch
Spezialisierung lösen ließe.
Was könnte noch Schwierigkeiten bereiten?
//~~ zunächst eine Hilfsklasse: ~~
template<typename T, size_t C>
class simple_array {
T a_[C];
size_t sz_;
public:
simple_array() : sz_(0) {}
typedef T* iterator;
typedef const T* const_iterator;
void push_back(const T& x) { a_[sz_++] = x; }
size_t size() const { return sz_; }
size_t capacity() const { return C; }
void clear() { sz_ = 0; }
iterator begin() { return a_; }
const_iterator begin() const { return a_; }
iterator end() { return a_ + sz_; }
const_iterator end() const { return a_ + sz_; }
};
//~~ der eigentliche »fastvector«: ~~
template<typename T, size_t C = 20>
class fastvector {
simple_array<T, C> st_;
std::vector<T> vec_;
bool st_active;
void activate_vec() {
vec_.assign(st_.begin(), st_.end());
st_active = false;
}
public:
fastvector() : st_active(true) {}
typedef T* iterator;
typedef const T* const_iterator;
void push_back(const T& x) {
if (st_active) {
st_.push_back(x);
if (st_.size() >= C) activate_vec();
}
else
vec_.push_back(x);
}
iterator insert(iterator pos, const T& x) {
if (st_active) activate_vec();
return vec_.insert(pos, x);
}
template <typename input_iterator>
void insert(iterator pos,
input_iterator first,
input_iterator last) {
if (st_active) activate_vec();
vec_.insert(pos, first, last);
}
size_t size() const {
return st_active? st_.size() : vec_.size();
}
size_t capacity() const {
return st_active? st_.capacity() : vec_.capacity();
}
void clear() {
st_.clear(); st_active = true; vec_.clear();
}
iterator begin() {
return st_active? st_.begin() : vec_.begin();
}
const_iterator begin() const {
return st_active? st_.begin() : vec_.begin();
}
iterator end() {
return st_active? st_.end() : vec_.end();
}
const_iterator end() const {
return st_active? st_.end() : vec_.end();
}
};
Gruß,
Michael
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Hubert Schmid Guest
|
Posted: Sat Nov 29, 2003 6:46 pm Post subject: Re: vector auf dem Stack |
|
|
[email]s1234569 (AT) hotmail (DOT) com[/email] (Michael Trocken) writes:
[gekürzt]
| Quote: | template<typename T, size_t C
class simple_array {
T a_[C];
size_t sz_;
public:
simple_array() : sz_(0) {}
void push_back(const T& x) { a_[sz_++] = x; }
size_t size() const { return sz_; }
void clear() { sz_ = 0; }
};
|
Die Klasse funktioniert nur, wenn T einen Default-Constructor besitzt.
Außerdem solltest du in 'clear()' die Elemente zumindest mit dem
Default-Konstruktor initialisieren (besser contruct und destroy
verwenden), sonst handelst du dir schnell ein "Memory-Leak" ein.
Beispiel:
{
simple_array a;
for (size_t i = 0; i < 100; ++i)
a.push_back(shared_array
a.clear();
// lang dauernde Berechnung
...
}
Gruß, Hubert
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Olaf Krzikalla Guest
|
Posted: Mon Dec 01, 2003 10:52 am Post subject: Re: vector auf dem Stack |
|
|
Hi,
Hubert Schmid wrote:
| Quote: | Die Klasse funktioniert nur, wenn T einen Default-Constructor besitzt.
Das ist aber OK, da auch vector für T einen Default-Constructor |
einfordert. Das IMHO größere Problem dieses Ansatzes ist, dass
tatsächlich auch 20 Elemente sofort angelegt werden. Das führt zu
Performanceeinbußen und - allerdings selten - auch zu zu echten
Schwierigkeiten (z.B. bei Klassen, die ihre Instanzenzahl zählen).
Besser wäre es, ein char[sizeof(T) * C] - Feld zu verwenden und darüber
dann mit construct und destroy wie bei einem normalen std::vector zu
operieren.
Ciao Olaf
PS: char[sizeof(T) * C] ist theoretisch nicht ganz wasserdicht
(undefiniertes Alignment). Praktisch wird es aber überall so gemacht.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Schaaf Guest
|
Posted: Mon Dec 01, 2003 11:27 am Post subject: Re: vector auf dem Stack |
|
|
"Olaf Krzikalla" <Entwicklung (AT) reico (DOT) de> schrieb:
| Quote: | Das ist aber OK, da auch vector für T einen Default-Constructor
einfordert.
|
Nein.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
André Pönitz Guest
|
Posted: Tue Dec 02, 2003 7:13 am Post subject: Re: vector auf dem Stack |
|
|
Olaf Krzikalla <Entwicklung (AT) reico (DOT) de> wrote:
| Quote: | Hi,
Hubert Schmid wrote:
Die Klasse funktioniert nur, wenn T einen Default-Constructor besitzt.
Das ist aber OK, da auch vector für T einen Default-Constructor
einfordert.
|
Tut er aber nicht. Muss nur 'copiable' und 'assignable' sein.
Andre'
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|