std::vector
verwendet den Heap. Meine Güte, was für eine Verschwendung wäre das nur für eine const
Plausibilitätsprüfung. Der Punkt std::vector
ist dynamisches Wachstum zur Laufzeit, nicht irgendeine alte Syntaxprüfung, die zur Kompilierungszeit durchgeführt werden sollte. Wenn Sie nicht wachsen werden, erstellen Sie eine Klasse, die ein normales Array umschließt.
#include <stdio.h>
template <class Type, size_t MaxLength>
class ConstFixedSizeArrayFiller {
private:
size_t length;
public:
ConstFixedSizeArrayFiller() : length(0) {
}
virtual ~ConstFixedSizeArrayFiller() {
}
virtual void Fill(Type *array) = 0;
protected:
void add_element(Type *array, const Type & element)
{
if(length >= MaxLength) {
// todo: throw more appropriate out-of-bounds exception
throw 0;
}
array[length] = element;
length++;
}
};
template <class Type, size_t Length>
class ConstFixedSizeArray {
private:
Type array[Length];
public:
explicit ConstFixedSizeArray(
ConstFixedSizeArrayFiller<Type, Length> & filler
) {
filler.Fill(array);
}
const Type *Array() const {
return array;
}
size_t ArrayLength() const {
return Length;
}
};
class a {
private:
class b_filler : public ConstFixedSizeArrayFiller<int, 2> {
public:
virtual ~b_filler() {
}
virtual void Fill(int *array) {
add_element(array, 87);
add_element(array, 96);
}
};
const ConstFixedSizeArray<int, 2> b;
public:
a(void) : b(b_filler()) {
}
void print_items() {
size_t i;
for(i = 0; i < b.ArrayLength(); i++)
{
printf("%d\n", b.Array()[i]);
}
}
};
int main()
{
a x;
x.print_items();
return 0;
}
ConstFixedSizeArrayFiller
und ConstFixedSizeArray
sind wiederverwendbar.
Die erste ermöglicht die Überprüfung der Laufzeitgrenzen während der Initialisierung des Arrays (wie ein Vektor könnte), die später const
nach dieser Initialisierung werden kann.
Die zweite ermöglicht die Zuweisung des Arrays innerhalb ein anderes Objekt, das auf dem Heap oder einfach der Stapel sein könnte, wenn das das Objekt ist. Es gibt keine Verschwendung von Zeit, die vom Heap zugewiesen wird. Es führt auch eine Kompilierungszeitprüfung für das Array durch.
b_filler
ist eine kleine private Klasse, um die Initialisierungswerte bereitzustellen. Die Größe des Arrays wird zum Zeitpunkt der Kompilierung mit den Vorlagenargumenten überprüft, sodass keine Möglichkeit besteht, sich außerhalb der Grenzen zu bewegen.
Ich bin sicher, es gibt exotischere Möglichkeiten, dies zu ändern. Dies ist ein erster Stich. Ich denke, dass man mit Klassen den Mangel des Compilers ziemlich gut ausgleichen kann.
Das Problem dabei ist, dass es Vektoren verwendet, die zusätzlichen Overhead verursachen. – vy32
Das Problem ist nicht, dass es Vektoren oder eine Art von Speicher im Vergleich zu anderen verwendet. Sie können den Vektor nicht direkt mit einer beliebigen Menge von Werten initialisieren. @ CharlesB techinique arbeitet mit Boost oder Std, um es in zwei Schritten zu tun. –