Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In einem C++/CX-Programm können Sie STL-Container (Standard Template Library, Standardvorlagenbibliothek) oder jeden anderen benutzerdefinierten Auflistungstyp frei verwenden. Wenn Sie jedoch Auflistungen über die Windows-Runtime-Anwendungsbinärdateischnittstelle (ABI) übergeben – beispielsweise an ein XAML-Steuerelement oder einen JavaScript-Client – müssen Sie Windows-Runtime-Auflistungstypen verwenden.
Die Windows-Runtime definiert die Schnittstellen für Auflistungen und verwandte Typen, und C++/CX stellt die konkreten C++-Implementierungen in der Headerdatei „collection.h“ bereit. Diese Abbildung zeigt die Beziehungen zwischen den Auflistungstypen:
Die Platform::Collections::Vector-Klasse ähnelt der std::vector-Klasse.
Die Platform::Collections::Map-Klasse ähnelt der Klasse "std::map".
Platform::Collections::VectorView-Klasse und Platform::Collections::MapView-Klasse sind schreibgeschützte Versionen von
Vector
undMap
.Iteratoren werden im Platform::Collections-Namespace definiert. Diese Iteratoren erfüllen die Anforderungen für STL-Iteratoren und ermöglichen die Verwendung von std::find, std::count_if und anderen STL-Algorithmen für alle Windows::Foundation::Collections-Schnittstellentypen oder Platform::Collections konkreten Typ. Das heißt, Sie können beispielsweise eine Auflistung in einer Windows-Runtime-Komponente durchlaufen, die in C# erstellt wurde, und einen STL-Algorithmus darauf anwenden.
Wichtig
Die Proxyiteratoren
VectorIterator
undVectorViewIterator
verwenden die ProxyobjekteVectoryProxy<T>
undArrowProxy<T>
, um eine Verwendung mit STL-Containern zu ermöglichen. Weitere Informationen finden Sie unter "VectorProxy-Elemente" weiter unten in diesem Artikel.Die C++/CX-Auflistungstypen unterstützen die gleichen Threadsicherheitsgarantien wie STL-Container.
Windows::Foundation::Collections::IObservableVector und Windows::Foundation::Collections::IObservableMap definieren Ereignisse, die ausgelöst werden, wenn sich die Sammlung auf verschiedene Weise ändert. Durch die Implementierung dieser Schnittstellen unterstützen Platform::Collections::Map and Platform::Collections::Vector databinding with XAML collections. Wenn Sie beispielsweise einen
Vector
mit einer Datenbindung zu einemGrid
haben und ein Element einer Auflistung hinzufügen, wird die Änderung in die Benutzeroberfläche des Rasters übernommen.
Verwendung von Vektoren
Wenn Ihre Klasse einen Sequenzcontainer an eine andere Komponente für Windows-Runtime übergeben muss, verwenden Sie Windows::Foundation::Collections:: IVector<T> als Parameter oder Rückgabetyp und Platform::Collections::Vector<T> als konkrete Implementierung. Wenn Sie versuchen, einen Vector
-Typ in einem öffentlichen Rückgabewert oder Parameter zu verwenden, wird der Compilerfehler C3986 ausgelöst. Sie können das Problem beheben, indem Sie den Vector
in einen IVector
ändern.
Wichtig
Wenn Sie eine Sequenz im eigenen Programm übergeben, verwenden Sie entweder Vector
oder std::vector
, da sie effizienter als IVector
sind. Verwenden Sie IVector
nur, wenn Sie den Container über die ABI übergeben.
Das Windows-Runtime-Typsystem unterstützt nicht das Konzept von verzweigten Arrays. Deshalb können Sie ein IVector<Platform::Array<T>>
nicht als Rückgabewert oder Methodenparameter übergeben. Um ein verzweigtes Array oder eine Sequenz von Sequenzen an die ABI zu übergeben, verwenden Sie IVector<IVector<T>^>
.
Vector<T>
stellt die Methoden bereit, die zum Hinzufügen, Entfernen und das Zugreifen auf Elemente in der Auflistung erforderlich sind, und kann implizit zu IVector<T>
konvertiert werden. Sie können STL-Algorithmen auch bei Instanzen von Vector<T>
verwenden. Das folgende Beispiel veranschaulicht die grundlegende Verwendung. Die Startfunktion und die Endfunktion stammen hier aus dem Platform::Collections
Namespace, nicht aus dem std
Namespace.
#include <collection.h>
#include <algorithm>
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation::Collections;
void Class1::Test()
{
Vector<int>^ vec = ref new Vector<int>();
vec->Append(1);
vec->Append(2);
vec->Append(3);
vec->Append(4);
vec->Append(5);
auto it =
std::find(begin(vec), end(vec), 3);
int j = *it; //j = 3
int k = *(it + 1); //or it[1]
// Find a specified value.
unsigned int n;
bool found = vec->IndexOf(4, &n); //n = 3
// Get the value at the specified index.
n = vec->GetAt(4); // n = 3
// Insert an item.
// vec = 0, 1, 2, 3, 4, 5
vec->InsertAt(0, 0);
// Modify an item.
// vec = 0, 1, 2, 12, 4, 5,
vec->SetAt(3, 12);
// Remove an item.
//vec = 1, 2, 12, 4, 5
vec->RemoveAt(0);
// vec = 1, 2, 12, 4
vec->RemoveAtEnd();
// Get a read-only view into the vector.
IVectorView<int>^ view = vec->GetView();
}
Wenn der vorhandene Code std::vector
verwendet und Sie ihn in einer Windows-Runtime-Komponente wiederverwenden möchten, benutzen Sie einfach einen der Vector
-Konstruktoren, der einen std::vector
oder ein Paar Iteratoren akzeptiert, um einen Vector
an dem Punkt zu erstellen, an dem Sie die Auflistung über die ABI übergeben. Im folgenden Beispiel wird gezeigt, wie der Vector
-Bewegungskonstruktor zur effizienten Initialisierung von std::vector
verwendet wird. Nach dem Verschiebungsvorgang ist die ursprüngliche vec
-Variable nicht mehr gültig.
//#include <collection.h>
//#include <vector>
//#include <utility> //for std::move
//using namespace Platform::Collections;
//using namespace Windows::Foundation::Collections;
//using namespace std;
IVector<int>^ Class1::GetInts()
{
vector<int> vec;
for(int i = 0; i < 10; i++)
{
vec.push_back(i);
}
// Implicit conversion to IVector
return ref new Vector<int>(std::move(vec));
}
Wenn Sie einen Vektor von Zeichenfolgen haben, die Sie an einem zukünftigen Punkt über die ABI übergeben müssen, müssen Sie entscheiden, ob die Zeichenfolgen zuerst als std::wstring
-Typen oder als Platform::String^
-Typen erstellt werden sollen. Wenn die Zeichenfolgen einen hohen Verarbeitungsaufwand erfordern, verwenden Sie wstring
. Erstellen Sie andernfalls die Zeichenfolgen als Platform::String^
-Typen, und vermeiden Sie den Aufwand einer späteren Konvertierung. Außerdem müssen Sie festlegen, ob diese Zeichenfolgen intern in einem std::vector
oder in einem Platform::Collections::Vector
abgelegt werden sollen. Im Allgemeinen sollten Sie std::vector
verwenden und nur dann einen Platform::Vector
erstellen, wenn Sie den Container über die ABI übergeben.
Werttypen im Vektor
Jedes Element, das in einer Platform::Collections::Vector gespeichert werden soll, muss den Gleichheitsvergleich unterstützen, entweder implizit oder mithilfe eines von Ihnen bereitgestellten benutzerdefinierten Std::equal_to-Vergleichselements . Alle Verweistypen und alle skalaren Typen unterstützen implizit Übereinstimmungsvergleiche. Bei nicht skalaren Werttypen wie Windows::Foundation::D ateTime oder für benutzerdefinierte Vergleiche – z objA->UniqueID == objB->UniqueID
. B. – müssen Sie ein benutzerdefiniertes Funktionsobjekt bereitstellen.
VectorProxy-Elemente
Platform::Collections::VectorIterator und Platform::Collections::VectorViewIterator ermöglichen die Verwendung von range for
Schleifen und Algorithmen wie std::sort mit einem IVector<T-Container> . Auf IVector
-Elemente kann jedoch nicht über die C++-Zeiger-Dereferenzierung zugegriffen werden. Der Zugriff erfolgt ausschließlich über die GetAt- und SetAt-Methoden. Daher verwenden diese Iteratoren die Proxyklassen Platform::Details::VectorProxy<T>
und Platform::Details::ArrowProxy<T>
, um Zugriff auf die einzelnen Elemente über die *-, ->- und []-Operatoren zu ermöglichen, wie es von der Standardbibliothek benötigt wird. Streng genommen ist bei einer IVector<Person^> vec
der Typ von *begin(vec)
VectorProxy<Person^>
. Allerdings ist das Proxyobjekt fast immer für Ihren Code transparent. Diese Proxyobjekte werden nicht dokumentiert, da sie nur für die interne Verwendung durch Iteratoren bestimmt sind. Es ist jedoch hilfreich zu wissen, wie der Mechanismus funktioniert.
Wenn Sie eine bereichsbezogene for
-Schleife über IVector
-Container verwenden, verwenden Sie auto&&
, damit die Iteratorvariable korrekt an die VectorProxy
-Elemente gebunden werden kann. Bei Verwendung auto&
wird die Compilerwarnung C4239 ausgelöst und VectoryProxy
im Warntext erwähnt.
Die folgende Abbildung zeigt ein Beispiel für eine range for
-Schleife über eine IVector<Person^>
. Beachten Sie, dass die Ausführung am Haltepunkt in Zeile 64 beendet wird. Das QuickWatch-Fenster zeigt, dass die Iteratorvariable p
tatsächlich ein VectorProxy<Person^>
ist, das über m_v
und m_i
Mitgliedsvariablen verfügt. Wenn Sie jedoch GetType
für diese Variable aufrufen, gibt sie den identischen Typ zur Instanz Person
p2
zurück. Die Erkenntnis ist, dass obwohl VectorProxy
und ArrowProxy
möglicherweise in QuickWatch, dem Debugger, bestimmten Compilerfehlern oder an anderen Stellen erscheinen, Sie normalerweise keinen expliziten Code dafür schreiben müssen.
Ein Szenario, in dem Sie Code um das Proxyobjekt herum schreiben müssen, ist, wenn Sie eine dynamic_cast
für die Elemente durchführen müssen, zum Beispiel, wenn Sie nach XAML-Objekte eines bestimmten Typs in einer UIElement
-Elementauflistung suchen. In diesem Fall müssen Sie das Element zuerst in Platform::Object^ umwandeln und dann die dynamische Umwandlung ausführen:
void FindButton(UIElementCollection^ col)
{
// Use auto&& to avoid warning C4239
for (auto&& elem : col)
{
Button^ temp = dynamic_cast<Button^>(static_cast<Object^>(elem));
if (nullptr != temp)
{
// Use temp...
}
}
}
Verwendung von Zuordnungen
In diesem Beispiel wird gezeigt, wie man Elemente in ein Platform::Collections::Map einfügt und nachschlagen kann, um sie dann als schreibgeschützten Map
-Typ zurückzugeben.
//#include <collection.h>
//using namespace Platform::Collections;
//using namespace Windows::Foundation::Collections;
IMapView<String^, int>^ Class1::MapTest()
{
Map<String^, int>^ m = ref new Map<String^, int >();
m->Insert("Mike", 0);
m->Insert("Dave", 1);
m->Insert("Doug", 2);
m->Insert("Nikki", 3);
m->Insert("Kayley", 4);
m->Insert("Alex", 5);
m->Insert("Spencer", 6);
// PC::Map does not support [] operator
int i = m->Lookup("Doug");
return m->GetView();
}
Im Allgemeinen sollten Sie für die interne Zuordnungsfunktionalität aus Leistungsgründen vorzugsweise den Typ std::map
verwenden. Wenn Sie den Container über die ABI übergeben müssen, erstellen Sie eine Platform::Collections::Map aus der std::map und geben sie Map
als Windows::Foundation::Collections::IMap zurück. Wenn Sie versuchen, einen Map
-Typ in einem öffentlichen Rückgabewert oder Parameter zu verwenden, wird der Compilerfehler C3986 ausgelöst. Sie können das Problem beheben, indem Sie den Map
in einen IMap
ändern. In einigen Fällen, beispielsweise wenn Sie nur wenige Suchen oder Einfügungen ausführen und die Auflistung häufig über die ABI übergeben, ist es möglicherweise weniger Aufwand, gleich Platform::Collections::Map
zu verwenden und die Konvertierung von std::map
zu vermeiden. Vermeiden Sie in jedem Fall Such- und Einfügevorgänge bei einer IMap
, da diese der am wenigsten leistungsfähige der drei Typen ist. Konvertieren Sie in IMap
nur dann, wenn Sie den Container über die ABI übergeben.
Werttypen in der Zuordnung
Elemente in einer Plattform::Collections::Map werden sortiert. Jedes Element, das in einem Map
Element gespeichert werden soll, muss einen geringeren Vergleich mit einer strengen schwachen Sortierung unterstützen, entweder implizit oder mithilfe eines benutzerdefinierten stl::less-Vergleichs , den Sie bereitstellen. Skalare Typen unterstützen den Vergleich implizit. Für nicht skalare Werttypen wie Windows::Foundation::DateTime
oder für benutzerdefinierte Vergleiche – z. B. objA->UniqueID < objB->UniqueID
– müssen Sie einen benutzerdefinierten Vergleichsoperator bereitstellen.
Auflistungstypen
Auflistungen sind in vier Kategorien unterteilt: änderbare Versionen und schreibgeschützte Versionen von Sequenzauflistungen und assoziativen Auflistungen. Darüber hinaus verbessert C++/CX Auflistungen durch die Bereitstellung von drei Iteratorklassen, die den Zugriff auf Auflistungen vereinfachen.
Elemente einer modifizierbaren Auflistung können geändert werden, aber Elemente einer schreibgeschützten Auflistung, die als Ansicht bezeichnet wird, können nur gelesen werden. Auf Elemente einer Platform::Collections::Vector orPlatform::Collections::VectorView-Auflistung kann mithilfe eines Iterators oder des Vector::GetAt und eines Indexes zugegriffen werden. Auf Elemente einer assoziativen Sammlung kann mithilfe der Funktion Map::Lookup und eines Schlüssels zugegriffen werden.
Platform::Collections::Map-Klasse
Eine änderbare, assoziative Auflistung. Zuordnungselemente sind Schlüssel-Wert-Paare. Sowohl das Suchen nach einem Schlüssel, um den zugeordneten Wert abzurufen, als auch das Durchlaufen aller Schlüssel-Wert-Paare werden unterstützt.
Map
und MapView
sind als Vorlagen für <K, V, C = std::less<K>>
vorhanden. Daher können Sie den Vergleichsoperator anpassen. Darüber hinaus sind Vector
und VectorView
auf <T, E = std::equal_to<T>>
vorlagenbasiert, damit Sie das Verhalten von IndexOf()
anpassen können. Dies ist vor allem für Vector
und VectorView
von Wertstrukturen wichtig. Um beispielsweise einen Vector<Windows::Foundation::DateTime> zu erstellen, müssen Sie einen benutzerdefinierten Vergleichsoperator bereitstellen, da DateTime den Operator == nicht überlädt.
Platform::Collections::MapView-Klasse
Eine schreibgeschützte Version von Map
.
Platform::Collections::Vector-Klasse
Eine änderbare Sequenzauflistung.
Vector<T>
unterstützt zufälligen Zugriff auf Konstantenzeit und amortisierte Anfügevorgänge mit konstanter Zeit.
Platform::Collections::VectorView-Klasse
Eine schreibgeschützte Version von Vector
.
Platform::Collections::InputIterator-Klasse
Ein STL-Iterator, der die Anforderungen eines STL-Eingabeiterators erfüllt.
Platform::Collections::VectorIterator-Klasse
Ein STL-Iterator, der die Anforderungen eines änderbaren STL-Iterators mit Direktzugriff erfüllt.
Platform::Collections::VectorViewIterator-Klasse
Ein STL-Iterator, der die Anforderungen eines STL-const
-Iterators mit Direktzugriff erfüllt.
begin() und end() -Funktionen
Zur Vereinfachung der Verwendung des STL zur Verarbeitung von Vector
, VectorView
, Map
, MapView
und beliebigen Windows::Foundation::Collections
-Objekten unterstützt C++/CX Überladungen der nicht-member Funktionen Begin und End.
Die folgende Tabelle zeigt die verfügbaren Iteratoren und Funktionen auf.
Iteratoren | Funktionen |
---|---|
Plattform::Sammlungen::VectorIterator<T> (Speichert Windows::Foundation::Collections:: IVector<T> und int.) |
beginnen/ end(Windows::Foundation::Collections:: IVector<T>) |
Plattform::Sammlungen::VectorViewIterator<T> (Intern speichert IVectorView<T>^ und int.) |
anfangen/ end (IVectorView<T>^) |
Plattform::Sammlungen::InputIterator<T> (Speichert IIterator<T>^ intern und T.) |
beginnen/ end (IIterable<T>) |
Plattform::Sammlungen::InputIterator<IKeyValuePair<K, V>^> (Speichert IIterator<T>^ intern und T.) |
anfangen/ end (IMap<K,V>. |
Plattform::Sammlungen::InputIterator<IKeyValuePair<K, V>^> (Speichert IIterator<T>^ intern und T.) |
anfangen/ end (Windows::Foundation::Collections::IMapView) |
Änderungsereignisse bei Auflistungen
Vector
und Map
unterstützen Datenbindung in XAML-Auflistungen durch Implementieren von Ereignissen, die auftreten, wenn ein Auflistungsobjekt geändert oder zurückgesetzt wird oder wenn ein Element in einer Auflistung eingefügt, aus dieser entfernt oder geändert wird. Sie können zwar eigene Typen schreiben, die Datenbindung unterstützen, können jedoch nicht von Map
oder von Vector
erben, da diese Typen versiegelt sind.
Die Windows::Foundation::Collections::VectorChangedEventHandler und Windows::Foundation::Collections::MapChangedEventHandler Delegaten spezifizieren die Signaturen für Ereignishandler für Sammlungsänderungsereignisse. Die öffentliche Enumeration-Klasse Windows::Foundation::Collections::CollectionChange, sowie die Platform::Collection::Details::MapChangedEventArgs
- und Platform::Collections::Details::VectorChangedEventArgs
-Verweisklassen, speichern die Ereignisargumente, um die Ursache des Ereignisses zu ermitteln.
*EventArgs
-Typen werden im Details
-Namespace definiert, da Sie sie nicht explizit erstellen oder nutzen müssen, wenn Sie Map
oder Vector
verwenden.