Frage

Ich habe einen Vektor, den ich mit einer bekannten Menge von Elementen (N) am Laden.

Die Verarbeitung erstellt dynamisch neue Elemente, die den Vektor angehängt werden.

Ich erwarte etwa 2 * N zusätzliche Elemente erstellt werden, so dass ich die Größe des Vektors 3 * N.

Wenn die zusätzlichen Elemente, die nicht überschreiten, ich möchte ein Programm abbrechen, anstatt eine dynamische Expansion des Vektors.

Gibt es eine Möglichkeit, das zu erkennen, das ist portabel zwischen AIX / TRU64 / Linux?

War es hilfreich?

Lösung

erkennen, was? Ob der Vektor der Größe verändert werden? Ob es gewesen ist?

Die einzige wirkliche Möglichkeit, dies zu erreichen, ist Funktionalität bereitzustellen Überprüfung entweder in einem benutzerdefinierten allocator oder eine Funktion, die Elemente auf den Vektor erstellt.

z

template<class T> 
void add_element(std::vector<T>& container, T const& v)
{
  if (container.capacity()+1 >= 3*N)
  {
    // terminate/exception/whatever
  }

 container.push_back(v);
}

Andere Tipps

Warum verwenden Sie einen Vektor? Der springende Punkt des Vektors ist dynamisch zu erweitern, wenn nötig.

Statt eine Klasse zu machen, um den Vektor zu übertragen, machen nur eine Klasse zu einer einfachen Anordnung zu delegieren. Haben Sie Ihre push_back die Größe überprüfen und abbrechen, wenn nötig.

Erstellen Sie Ihre eigene Klasse, die auf den Vektor übertragen wird. Und überprüfen Größe in Ihrem eigenen push_back.

Wenn Sie die Größe bei der Kompilierung kennen, oder vielleicht mit einem std :: tr1 :: array (oder boost :: array ) wäre eine bessere Wahl sein. Es hält eine feste Größe und überprüfen Sie den Zugriff wie std :: vector.

Wenn Sie jedoch wissen, dass es nur zur Laufzeit, wie gesagt andere hier, sollten Sie Ihren Vektor in einer Klasse mit spezifischen Funktionen kapseln, die die Bedingungen überprüfen Sie (über Behauptungen zum Beispiel) werden sollen.

In diesem letzten Ansatz, würde ich vorschlagen, wenn Sie die maximale Größe bei der Vektor Schöpfung wissen können, reservieren (std :: vector :: Reserve ()) die maximale Größe des Vektors in der Einkapselung Klassenkonstruktors (oder Initialisierungsfunktion). Auf diese Weise wird es durch den Vektor selbst nicht mehr Speicher Manipulationen sein (nur wenn das Vektorelemente Konstruktor / Destruktor solche Manipulationen tun). Dann eine einfache Behauptung hinzufügen, die überprüft, ob die Vektor-Kapazität (std :: vector :: Kapazität ()) nie am Anfang und Ende aller Funktionen der Klasse geändert werden Sie helfen, sicherzustellen, dass es Speicher nicht bewegen.

Zum Beispiel (DATA_MAX_SIZE unter der Annahme ist eine Standard maximale Größe irgendwo definiert):

template< typename MyType >
class MyData
{
public:
    MyData( unsigned long max_size = DATA_MAX_SIZE )
        : m_max_size( max_size )
        { m_data.reserve( m_max_size ); }

    void add( const MyType& value ) { check_capacity(); m_data.push_back( value ); check_capacity(); }



private:

    std::vector< MyType > m_data;
    const unsigned long m_max_size;

    void check_capacity() { if( m_data.capacity() != m_max_size ) throw Exception("Useful error message here!" ); }

};

Oder so ähnlich ...

std Klassen verwenden, um ein allocator genannt jedes Mal wenn Sie ein Element einzufügen. Sie können einen neuen allocator aus dem std :: alocator, und fügen Sie alle Arten von Kontrollen / Spuren benötigen Sie erben schreiben.

(ich das vorher, aber es dauerte eine Weile, funktionierenden Code zu machen.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top