Verzamelingen (C++/CX)
In een C++/CX-programma kunt u gratis gebruikmaken van STL-containers (Standard Template Library) of een ander door de gebruiker gedefinieerd verzamelingstype. Wanneer u verzamelingen echter heen en weer doorgeeft via de binaire interface van de Windows Runtime-toepassing (ABI), bijvoorbeeld naar een XAML-besturingselement of een JavaScript-client, moet u typen Windows Runtime-verzamelingen gebruiken.
De Windows Runtime definieert de interfaces voor verzamelingen en gerelateerde typen, en C++/CX biedt de concrete C++-implementaties in het headerbestand collection.h. In deze afbeelding ziet u de relaties tussen de verzamelingstypen:
De Platform::Collections::Vector-klasse lijkt op de std::vectorklasse.
De Platform::Collections::Map-klasse lijkt op de std::mapklasse.
Platform::Collections::VectorView-klasse en Platform::Collections::MapView-klasse zijn alleen-lezenversies van
Vector
enMap
.Iterators worden gedefinieerd in de Platform::Collections-naamruimte. Deze iterators voldoen aan de vereisten voor STL-iterators en maken het gebruik van std::find, std::count_ifen andere STL-algoritmen mogelijk op elk Windows::Foundation::Collections interfacetype of Platform::Collections specifiek type. Dit betekent bijvoorbeeld dat u een verzameling kunt herhalen in een Windows Runtime-onderdeel dat in C# is gemaakt en waarop een STL-algoritme wordt toegepast.
Belangrijk
Proxy-iterators
VectorIterator
enVectorViewIterator
gebruikmaken van proxyobjectenVectoryProxy<T>
enArrowProxy<T>
om gebruik met STL-containers mogelijk te maken. Zie VectorProxy-elementen verderop in dit artikel voor meer informatie.De C++/CX-verzamelingstypen ondersteunen dezelfde threadveiligheidsgaranties die door STL-containers worden ondersteund.
Windows::Foundation::Collections::IObservableVector en Windows::Foundation::Collections::IObservableMap gebeurtenissen definiëren die worden geactiveerd wanneer de verzameling op verschillende manieren verandert. Door deze interfaces te implementeren, ondersteunen Platform::Collections::Map en Platform::Collections::Vector gegevensbinding met XAML-verzamelingen. Als u bijvoorbeeld een
Vector
hebt die datagebonden is aan eenGrid
, wordt de wijziging doorgevoerd in de Grid-UI wanneer u een item aan een verzameling toevoegt.
Vectorgebruik
Wanneer uw klasse een reekscontainer moet doorgeven aan een ander Windows Runtime-onderdeel, gebruikt u Windows::Foundation::Collections:: IVector<T> als parameter of retourtype, en Platform::Collections::Vector<T> als de concrete implementatie. Als u probeert een Vector
-type te gebruiken in een publieke retourwaarde of parameter, treedt de compilerfout C3986 op. U kunt de fout oplossen door de Vector
te wijzigen in een IVector
.
Belangrijk
Als u een reeks binnen uw eigen programma doorgeeft, gebruikt u Vector
of std::vector
omdat ze efficiënter zijn dan IVector
. Gebruik IVector
alleen wanneer u de container doorgeeft aan de ABI.
Het Windows Runtime-typesysteem biedt geen ondersteuning voor het concept van gelabelde matrices en daarom kunt u geen IVector<Platform::Array<T>>
doorgeven als een retourwaarde of methodeparameter. Als u een gekartelde array of een sequentie van sequenties wilt doorgeven aan de ABI, gebruikt u IVector<IVector<T>^>
.
Vector<T>
biedt de methoden die nodig zijn voor het toevoegen, verwijderen en openen van items in de verzameling, en deze is impliciet converteerbaar naar IVector<T>
. U kunt ook STL-algoritmen gebruiken op exemplaren van Vector<T>
. In het volgende voorbeeld ziet u een aantal basisgebruiken. De beginfunctie en eindfunctie hier zijn afkomstig uit de Platform::Collections
naamruimte, niet de std
naamruimte.
#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();
}
Als u bestaande code hebt die gebruikmaakt van std::vector
en u deze opnieuw wilt gebruiken in een Windows Runtime-onderdeel, gebruikt u slechts een van de Vector
constructors die een std::vector
of een paar iterators nodig hebben om een Vector
te maken op het moment waarop u de verzameling doorgeeft over de ABI. In het volgende voorbeeld zie je hoe je met de Vector
-verplaatsingsconstructor efficiënt initialiseert vanuit een std::vector
. Na de verplaatsingsbewerking is de oorspronkelijke vec
variabele niet meer geldig.
//#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));
}
Als u een vector van tekenreeksen hebt die u later moet doorgeven aan de ABI, moet u beslissen of u de tekenreeksen in eerste instantie wilt maken als std::wstring
types of als Platform::String^
types. Als u veel verwerking op de tekenreeksen moet uitvoeren, gebruikt u wstring
. Anders maakt u de tekenreeksen als Platform::String^
typen en vermijdt u de kosten voor het later converteren ervan. U moet ook bepalen of u deze tekenreeksen intern in een std:vector
of Platform::Collections::Vector
wilt plaatsen. Als algemene praktijk gebruikt u std::vector
en maakt u er vervolgens alleen een Platform::Vector
van wanneer u de container doorgeeft over de ABI.
Waardetypen in Vector
Elk element dat moet worden opgeslagen in een Platform::Collections::Vector moet ondersteuning bieden voor gelijkheidsvergelijking, impliciet of met behulp van een aangepaste std::equal_to comparator die u opgeeft. Alle referentietypen en alle scalaire typen ondersteunen impliciet gelijkheidsvergelijkingen. Voor niet-scalaire waardetypen zoals Windows::Foundation::D ateTimeof voor aangepaste vergelijkingen, bijvoorbeeld objA->UniqueID == objB->UniqueID
, moet u een aangepast functieobject opgeven.
VectorProxy-elementen
Platform::Collections::VectorIterator en Platform::Collections::VectorViewIterator maken het mogelijk om range for
lussen en algoritmen, zoals bijv. std::sort, te gebruiken met een IVector<T> container. Maar IVector
elementen kunnen niet worden benaderd via C++-aanwijzerdereferentie; toegang kan alleen worden verkregen via de GetAt- en SetAt- methoden. Daarom gebruiken deze iterators de proxyklassen Platform::Details::VectorProxy<T>
en Platform::Details::ArrowProxy<T>
om toegang te bieden tot de afzonderlijke elementen via *, ->en [] operators, zoals vereist door de standaardbibliotheek. Strikt genomen, gezien een IVector<Person^> vec
, is het type *begin(vec)
VectorProxy<Person^>
. Het proxyobject is echter bijna altijd transparant voor uw code. Deze proxyobjecten worden niet gedocumenteerd omdat ze alleen voor intern gebruik door de iterators worden gebruikt, maar het is handig om te weten hoe het mechanisme werkt.
Wanneer u een bereikgebaseerde for
lus over IVector
containers gebruikt, gebruikt u auto&&
om de iteratorvariabele in te schakelen om de VectorProxy
-elementen correct te binden. Als u auto&
gebruikt, wordt er een compilerwaarschuwing C4239- gegenereerd en wordt VectoryProxy
vermeld in de waarschuwingstekst.
De volgende illustratie toont een range for
lus over een IVector<Person^>
. U ziet dat de uitvoering is gestopt op het onderbrekingspunt op regel 64. In het venster QuickWatch ziet u dat de iteratorvariabele p
in feite een VectorProxy<Person^>
is met m_v
en m_i
lidvariabelen. Wanneer u echter GetType
aanroept voor deze variabele, wordt het identieke type geretourneerd aan het Person
exemplaar p2
. Het leerpunt is dat hoewel VectorProxy
en ArrowProxy
in QuickWatch-, het foutopsporingsprogramma, bepaalde compilerfouten of andere locaties kunnen verschijnen, u doorgaans niet expliciet voor hen hoeft te coderen.
Een scenario waarin u moet coderen rond het proxyobject is wanneer u een dynamic_cast
op de elementen moet uitvoeren, bijvoorbeeld wanneer u op zoek bent naar XAML-objecten van een bepaald type in een UIElement
elementverzameling. In dit geval moet u eerst het element casten naar Platform::Object^ en vervolgens de dynamische cast uitvoeren:
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...
}
}
}
Gebruik van kaarten
In dit voorbeeld ziet u hoe u items invoegt en opzoekt in een Platform::Collections::Mapen de Map
retour geeft als een alleen-lezen type Windows::Foundation::Collections::IMapView.
//#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();
}
Over het algemeen geeft u voor interne kaartfunctionaliteit de voorkeur aan het std::map
type om prestatie-redenen. Als u de container moet doorgeven aan de ABI, maakt u een Platform::Collections::Map uit de std::map en retourneert u de Map
als een Windows::Foundation::Collections::IMap. Als u probeert een type Map
te gebruiken in een publieke retourwaarde of parameter, treedt compilerfout C3986 op. U kunt de fout oplossen door de Map
te wijzigen in een IMap
. In sommige gevallen, bijvoorbeeld als u niet een groot aantal zoekacties of invoegingen maakt en u de verzameling vaak doorgeeft aan de ABI, kan het minder duur zijn om vanaf het begin Platform::Collections::Map
te gebruiken en de kosten voor het converteren van de std::map
te voorkomen. Vermijd in ieder geval opzoek- en invoegbewerkingen op een IMap
omdat deze het minst presterende van de drie typen zijn. Converteer naar IMap
alleen wanneer u de container door de ABI geeft.
Waardetypen in Kaart
Elementen in een Platform::Collections::Map zijn gerangschikt. Elk element dat moet worden opgeslagen in een Map
moet ondersteuning bieden voor minder dan vergelijking met strikte zwakke volgorde, impliciet of met behulp van een aangepaste stl::less comparator die u opgeeft. Scalaire typen ondersteunen impliciet de vergelijking. Voor niet-scalaire waardetypen, zoals Windows::Foundation::DateTime
, of voor aangepaste vergelijkingen, bijvoorbeeld objA->UniqueID < objB->UniqueID
, moet u een aangepaste vergelijking opgeven.
Verzamelingstypen
Verzamelingen worden onderverdeeld in vier categorieën: wijzigbare versies en alleen-lezen versies van reeksverzamelingen en associatieve verzamelingen. Daarnaast verbetert C++/CX verzamelingen door drie iteratorklassen te bieden die de toegang tot verzamelingen vereenvoudigen.
Elementen van een wijzigbare verzameling kunnen worden gewijzigd, maar elementen van een alleen-lezenverzameling, ook wel een weergavegenoemd, kunnen alleen worden gelezen. Elementen van een Platform::Collections::Vector ofPlatform::Collections::VectorView verzameling zijn toegankelijk met behulp van een iterator of de Vector::GetAt- en een index van de verzameling. Elementen van een associatieve verzameling kunnen worden geopend met behulp van de Map::Lookup en een sleutel van de verzameling.
Platform::Collecties::Kaart klasse
Een wijzigbare, associatieve verzameling. Kaartelementen zijn sleutel-waardeparen. Het opzoeken van een sleutel om de bijbehorende waarde op te halen en het doorlopen van alle sleutel-waardeparen wordt beide ondersteund.
Map
en MapView
zijn gebaseerd op <K, V, C = std::less<K>>
; daarom kunt u de comparator aanpassen. Daarnaast worden Vector
en VectorView
op <T, E = std::equal_to<T>>
sjabloon gemaakt, zodat u het gedrag van IndexOf()
kunt aanpassen. Dit is vooral belangrijk voor Vector
en VectorView
van waardestructuren. Als u bijvoorbeeld een Vector<Windows::Foundation::D ateTime>wilt maken, moet u een aangepaste comparator opgeven omdat DateTime de operator == niet overbelast.
Platform::Collections::MapView-klasse
Een lees-alleen versie van een Map
.
Platform::Collections::Vector-klasse
Een wijzigbare reeksverzameling.
Vector<T>
biedt ondersteuning voor constante willekeurige toegang en afgeschreven constante tijd toevoegbewerkingen.
Platform::Collections::VectorView-klasse
Een alleen-lezen-modus van een Vector
.
Platform::Collections::InputIterator-klasse
Een STL-iterator die voldoet aan de vereisten van een STL-invoer-iterator.
Platform::Collections::VectorIterator-klasse
Een STL-iterator die voldoet aan de vereisten van een STL-muteerbare iterator voor willekeurige toegang.
Platform::Collections::VectorViewIterator-klasse
Een STL-iterator die voldoet aan de vereisten van een STL-const
iterator voor willekeurige toegang.
de functies begin() en end()
Om het gebruik van de STL te vereenvoudigen voor het verwerken van Vector
, VectorView
, Map
, MapView
en willekeurige Windows::Foundation::Collections
objecten, ondersteunt C++/CX overbelastingen van de en eindfunctie niet-lidfuncties.
De volgende tabel bevat de beschikbare iterators en functies.
Iterators (herhalingsmechanismen) | Functies |
---|---|
Platform::Collections::VectorIterator<T> (Slaat intern Windows::Foundation::Collections:: IVector<T> en int op.) |
begin/ einde van(Windows::Foundation::Collections:: IVector<T>) |
Platform::Collections::VectorViewIterator<T> (Slaat intern IVectorView<T>^ en int op.) |
begin/ (IVectorView<T>^) |
Platform::Collections::InputIterator<T> (Slaat intern IIterator<T>^ en T.) |
begin/ (IIterable<T>) |
Platform::Collections::InputIterator<IKeyValuePair<K, V>^> (Slaat intern IIterator<T>^ en T.) |
begin/ (IMap<K,V>. |
Platform::Collections::InputIterator<IKeyValuePair<K, V>^> (Slaat intern IIterator<T>^ en T.) |
begin/ eind (Windows::Foundation::Collections::IMapView) |
Gebeurtenissen van verzamelingswijziging
Vector
en Map
ondersteuning bieden voor gegevensbinding in XAML-verzamelingen door gebeurtenissen te implementeren die optreden wanneer een verzamelingsobject wordt gewijzigd of opnieuw wordt ingesteld, of wanneer een element van een verzameling wordt ingevoegd, verwijderd of gewijzigd. U kunt uw eigen typen schrijven die ondersteuning bieden voor gegevensbinding, hoewel u niet kunt overnemen van Map
of Vector
omdat deze typen zijn verzegeld.
De Windows::Foundation::Collections::VectorChangedEventHandler en Windows::Foundation::Collections::MapChangedEventHandler gedelegeerden specificeren de signaturen voor gebeurtenishandlers voor wijziging van verzamelingen. De Windows::Foundation::Collections::CollectionChange openbare enum klasse en de Platform::Collection::Details::MapChangedEventArgs
en Platform::Collections::Details::VectorChangedEventArgs
referentieklassen slaan de gebeurtenisargumenten op om te bepalen wat de oorzaak van de gebeurtenis is. De *EventArgs
typen worden gedefinieerd in de Details
naamruimte, omdat u deze niet expliciet hoeft te maken of gebruiken wanneer u Map
of Vector
gebruikt.
Zie ook
Typesysteem
C++/CX Taalreferentie
verwijzing naar naamruimten