Erfüllt std :: vector die Containeranforderungen für Boost.Interprocess allocators?

8

In boost::interprocess documentation heißt es, dass Container im Shared Memory gespeichert werden müssen:

  1. STL-Container können nicht davon ausgehen, dass mit einem Zuordner zugeordneter Speicher mit anderen Zuordnern des gleichen Typs freigegeben werden kann. Alle Zuweisungsobjekte müssen nur dann den Wert "Gleich" vergleichen, wenn der mit einem Objekt zugewiesene Speicher mit dem anderen freigegeben werden kann. Dies kann nur zur Laufzeit mit operator==() getestet werden.
  2. Die internen Container von Containern sollten vom Typ allocator::pointer sein und die Container dürfen nicht annehmen, dass allocator::pointer ein roher Pointer ist.
  3. Alle Objekte müssen über allocator::construct und allocator::destroy functions konstruiert und zerstört werden.

Ich verwende gcc 4.7.1 mit -std = c ++ 11 (und boost 1.53). Ist es sicher, den unten definierten ShmVector -Typ zu verwenden?

%Vor%

Ich habe versucht, einen Dummy-Prozess, der diesen Typ verwendet, und es sieht aus wie es funktioniert, aber ich bin immer noch nicht sicher, dass der Vektor in gcc4.7.1 alle Anforderungen erfüllt. Ich bin mir besonders über die erste Anforderung nicht sicher.

%Vor%     
Gabor Marton 08.03.2013, 15:54
quelle

2 Antworten

0

In C ++ haben sich die 11 Zuweisungsregeln geringfügig geändert, aber ich glaube nicht, dass das Ihre Frage beeinflusst.

Sie möchten wahrscheinlich zuerst wissen, was Standard darüber sagt. Aber Sie möchten tatsächlich überprüfen, ob Ihre spezifische STL-Implementierung dem Standard entspricht und keine Fehler enthält.

Für den zweiten Teil würde ich dringend empfehlen, Quellen zu besuchen und einfach zu überprüfen, dass es eigentlich gar nicht so schwer ist.

Auch könnten Sie Ihre Tests schreiben, um zu sehen, ob es tatsächlich richtig funktioniert:

  • Erstellen Sie einen benutzerdefinierten Zuordner:
    • verwende einen benutzerdefinierten Typ als Zeiger, const pointer;
    • In construct() , destruct() Anzahl der Anrufe;
  • Erstellen Sie YourCustomType , das mit dem Zuordner verwendet werden soll, der auch die Anzahl der Konstruktionen / Zerstörungen zählt.
  • Erstellen Sie jetzt std::vetor<YourCustomType, YourCustomAllocator<YourCustomType>> instance, fügen Sie einige Elemente ein, löschen Sie den Vektor, zerstören Sie ihn und sehen Sie, ob:
    • Die Anzahl der Aufrufe von construct() destruct() ist gleich der Anzahl der Zerstörungen von Konstruktionen von YourCustomType .
    • typeid(YourCustomAllocator::pointer) == typeid(std::vetor<YourCustomType, YourCustomAllocator<YourCustomType>>::pointer)

So können Sie sicher sein, dass alle Einschränkungen gelten.

Wie für den ersten Teil der Frage, hier ist ein alten C ++ - Standard (nicht C ++ 11).

1 Es gibt keinen Weg (richtig implementiert) Vektor wird einen Zuordner aus dem Nichts nehmen. Es wird den von Ihnen bereitgestellten Allokator verwenden und für alles verwenden. Wie für operator ==, ist es in Boost's Allokator implementiert und es ist Boosts Problem, Operator == so arbeiten zu lassen, wie sie benötigen. Obwohl ich keine Bestätigung im Standard finden konnte.

2 Sofern es sich nicht um einen Fehler handelt, sollte std::vector<T, YourAllocator>::pointer der Zeiger des Zuweisers sein. cppreference.com sagt das und den Standard sagt das , (nach "Template class vector" suchen):

%Vor%

Obwohl derselbe Standard dies über Allokatoren aussagt : Implementierungen von Containern, die in dieser Internationalen Norm beschrieben sind   dürfen annehmen, dass ihr Allocator Template-Parameter erfüllt   die folgenden zwei zusätzlichen Anforderungen über die in Tabelle 6 hinaus.

- Alle Instanzen eines bestimmten Zuordnungstyps müssen inter-     veränderbar und immer gleich zu vergleichen.

- Der typedef-Memberpointer, const_pointer, size_type und differ     ence_type müssen T *, T const *, size_t und ptrdiff_t sein,     respektive.

Eigentlich erlaubt der Standard keine Zeigerarten, aber ich gehe davon aus, dass die tatsächlichen STL-Implementierungen funktionieren.

3 Überprüfen Sie einfach die std::vector<T>::clear() Methodenimplementierung, um zu sehen, ob allocator :: destroy aufgerufen wird. Überprüfen Sie die Implementierung von std::vector<T>::resize() method, um zu sehen, ob allocator :: construct verwendet wird. Ich war nicht in der Lage, Anforderung zu finden, zerstören und konstruieren in der Standard .

    
Artem Tokmakov 14.03.2013 18:52
quelle
0

Ich denke, die Antwort ist nein. Weil in der Praxis (in C ++ 98) und in der Theorie (C ++ 11 Standard) std::vector Zeiger nicht anders als T* sein kann.

Deshalb verwendet boost::interprocess::vector<T> boost::container::vector<T, boost::interprocess::allocator<T>> (anstelle von std::vector<T, boost::interprocess::allocator<T>> ).

    
alfC 07.07.2017 01:08
quelle