Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I ett C++/CX-program kan du använda STL-containrar (Standard Template Library) kostnadsfritt eller någon annan användardefinierad samlingstyp. Men när du skickar samlingar fram och tillbaka över windows Runtime-programmets binära gränssnitt (ABI) – till exempel till en XAML-kontroll eller till en JavaScript-klient – måste du använda samlingstyper för Windows Runtime.
Windows Runtime definierar gränssnitten för samlingar och relaterade typer, och C++/CX tillhandahåller de konkreta C++-implementeringarna i header-filen collection.h. Den här bilden visar relationerna mellan samlingstyperna:
Klassen
Platform::Collections::Vectorliknarstd::vectorklassen.Platform::Collections::VectorViewklass ochPlatform::Collections::MapViewklass är skrivskyddade versioner avVectorochMap.Iteratorer definieras i
Platform::Collectionsnamnområdet. Dessa iteratorer uppfyller kraven för STL-iteratorer och möjliggör användning avstd::find,std::count_ifoch andra STL-algoritmer på allaWindows::Foundation::Collectionsgränssnittstyper ellerPlatform::Collectionsbetongtyper. Det innebär till exempel att du kan iterera en samling i en Windows Runtime-komponent som skapas i C# och tillämpa en STL-algoritm på den.Important
Proxy iteratorer
VectorIteratorochVectorViewIteratoranvänder proxyobjektVectorProxy<T>ochArrowProxy<T>för att möjliggöra användning med STL-behållare. Mer information finns i VectorProxy-element senare i den här artikeln.C++/CX-samlingstyperna stöder samma gängsäkerhetsgarantier som STL-containrar stöder.
Windows::Foundation::Collections::IObservableVectorochWindows::Foundation::Collections::IObservableMapdefiniera händelser som utlöses när samlingen ändras på olika sätt. Genom att implementera dessa gränssnittPlatform::Collections::MapochPlatform::Collections::Vectorstödja databindning med XAML-samlingar. Om du till exempel har enVectorsom är databunden till enGrid, visas ändringen i rutnätsgränssnittet när du lägger till ett objekt i en samling.
Vektoranvändning
När klassen måste skicka en sekvenscontainer till en annan Windows Runtime-komponent använder Windows::Foundation::Collections::IVector<T> du som parameter eller returtyp och Platform::Collections::Vector<T> som konkret implementering. Om du försöker använda en Vector typ i ett offentligt returvärde eller en parameter genereras kompilatorfelet C3986. Du kan åtgärda felet genom att ändra Vector till en IVector.
Important
Om du skickar en sekvens i ditt eget program använder du antingen Vector eller std::vector eftersom de är effektivare än IVector. Använd endast IVector när du skickar containern över ABI.
Windows Runtime-typsystemet stöder inte begreppet ojämna matriser och därför kan du inte skicka en IVector<Platform::Array<T>> som ett returvärde eller en metodparameter. Om du vill skicka en ojämn matris eller en sekvens med sekvenser över ABI använder du IVector<IVector<T>^>.
Vector<T> innehåller de metoder som krävs för att lägga till, ta bort och komma åt objekt i samlingen, och det är implicit konvertibelt till IVector<T>. Du kan också använda STL-algoritmer på instanser av Vector<T>. I följande exempel visas viss grundläggande användning.
Funktionenbegin och end funktionen här kommer från Platform::Collections namnområdet, inte std namnområdet.
#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();
}
Om du har befintlig kod som använder std::vector och du vill återanvända den i en Windows Runtime-komponent använder du bara en av de Vector konstruktorer som tar en std::vector eller ett par iteratorer för att skapa en Vector vid den punkt där du skickar samlingen över ABI. I följande exempel visas hur du använder Vector-flyttkonstruktör för effektiv initiering från en std::vector. Efter flyttåtgärden är den ursprungliga vec variabeln inte längre giltig.
//#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));
}
Om du har en strängvektor som du måste skicka över ABI vid någon framtida tidpunkt måste du bestämma om du ska skapa strängarna från början som std::wstring typer eller som Platform::String^ typer. Om du behöver bearbeta strängarna mycket använder du wstring. Annars skapar du strängarna som Platform::String^ typer och undviker kostnaden för att konvertera dem senare. Du måste också bestämma om du vill placera dessa strängar internt i en std::vector eller Platform::Collections::Vector. Som allmän praxis använder du std::vector och skapar sedan en Platform::Vector från den bara när du skickar containern över ABI.
Värdetyper i Vector
Alla element som ska lagras i en Platform::Collections::Vector måste ha stöd för likhetsjämförelse, antingen implicit eller med hjälp av en anpassad std::equal_to jämförelse som du anger. Alla referenstyper och alla skalära typer stöder implicit likhetsjämförelser. För icke-skalära värdetyper som Windows::Foundation::DateTime, eller för anpassade jämförelser, till exempel , objA->UniqueID == objB->UniqueIDmåste du ange ett anpassat funktionsobjekt.
VectorProxy-elementen
Platform::Collections::VectorIterator och Platform::Collections::VectorViewIterator aktiverar användningen av range for-loopar och algoritmer som std::sort med en IVector<T>-container. Dock går det inte att komma åt IVector-element via C++-pekaravreferens; de kan endast nås via GetAt och SetAt-metoder. Därför använder dessa iteratorer proxyklasserna Platform::Details::VectorProxy<T> och Platform::Details::ArrowProxy<T> för att ge åtkomst till de enskilda elementen via *, ->och [] operatorer, enligt standardbiblioteket. Strängt taget, givet en IVector<Person^> vec, är typen av *begin(vec)VectorProxy<Person^>. Proxyobjektet är dock nästan alltid transparent för koden. Dessa proxyobjekt dokumenteras inte eftersom de endast är för internt bruk av iteratorerna, men det är användbart att veta hur mekanismen fungerar.
När du använder en intervallbaserad for-loop över IVector containrar använder du auto&& för att aktivera iteratorvariabeln för att binda korrekt till de VectorProxy elementen. Om du använder auto&aktiveras kompilatorvarningen C4239 och VectorProxy anges i varningstexten.
Följande bild visar en range for-loop över en IVector<Person^>. Observera att exekveringen stoppas vid brytpunkten på rad 64. Fönstret QuickWatch visar att iteratorvariabeln p i själva verket är en VectorProxy<Person^> som har m_v och m_i medlemsvariabler. Men när du anropar GetType för den här variabeln returneras den identiska typen till den Person instansen p2. Sammanfattningen är att även om VectorProxy och ArrowProxy kan visas i QuickWatch, vissa kompilatorfel eller andra platser i felsökaren, behöver du vanligtvis inte uttryckligen koda för dem.
Ett scenario där du måste koda runt proxyobjektet är när du måste utföra en dynamic_cast på elementen, till exempel när du letar efter XAML-objekt av en viss typ i en UIElement elementsamling. I det här fallet måste du först omvandla elementet till Platform::Object^ och sedan utföra den dynamiska gjutningen:
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...
}
}
}
Kartanvändning
Det här exemplet visar hur du infogar objekt och söker upp dem i en Platform::Collections::Map, och sedan returnerar Map som en skrivskyddad Windows::Foundation::Collections::IMapView datatyp.
//#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();
}
För interna kartfunktioner föredras i allmänhet typen std::map för prestandaskäl. Om du måste skicka containern över ABI skapar du en Platform::Collections::Map från std::map och returnerar Map som en Windows::Foundation::Collections::IMap. Om du försöker använda en Map typ i ett offentligt returvärde eller en parameter genereras kompilatorfelet C3986. Du kan åtgärda felet genom att ändra Map till en IMap. I vissa fall, till exempel om du inte gör ett stort antal sökningar eller infogningar, och du skickar samlingen via ABI ofta, kan det vara billigare att använda Platform::Collections::Map från början och undvika kostnaden för att konvertera std::map. Undvik i vilket fall som helst uppslags- och infogningsåtgärder på en IMap eftersom dessa är minst högpresterande av de tre typerna. Konvertera till IMap endast vid den punkt där du skickar containern över ABI.
Värdetyper i Map
Elementen i en Platform::Collections::Map är ordnade. Alla element som ska lagras i en Map måste ha stöd för mindre än jämförelse med strikt svag ordning, antingen implicit eller med hjälp av en anpassad std::less jämförelse som du anger. Skalära typer stöder jämförelsen implicit. För icke-skalära värdetyper som Windows::Foundation::DateTimeeller för anpassade jämförelser– till exempel objA->UniqueID < objB->UniqueID– måste du ange en anpassad jämförelse.
Samlingstyper
Samlingar delas in i fyra kategorier: ändringsbara versioner och skrivskyddade versioner av sekvenssamlingar och associativa samlingar. Dessutom förbättrar C++/CX samlingar genom att tillhandahålla tre iteratorklasser som förenklar åtkomsten av samlingar.
Element i en ändringsbar samling kan ändras, men element i en skrivskyddad samling, som kallas för en vy, kan bara läsas. Element i en Platform::Collections::Vector eller Platform::Collections::VectorView en samling kan nås med hjälp av en iterator eller samlingens Vector::GetAt och ett index. Element i en associativ samling kan nås med hjälp av samlingens Map::Lookup och en nyckel.
Klassen Platform::Collections::Map
En ändringsbar, associativ samling. Dessa kartelement är nyckel-värde-par. Att leta upp en nyckel för att hämta dess associerade värde och iterera genom alla nyckel/värde-par stöds båda.
Map och MapView mallas på <K, V, C = std::less<K>>; Därför kan du anpassa jämförelsen. Dessutom mallas Vector och VectorView på <T, E = std::equal_to<T>> så att du kan anpassa beteendet för IndexOf(). Detta är främst viktigt för Vector och VectorView av värdestrukturer. Om du till exempel vill skapa en Vector<Windows::Foundation::DateTime>måste du ange en anpassad jämförelse eftersom DateTime inte överbelastar operatorn == .
Klassen Platform::Collections::MapView
En skrivskyddad version av en Map.
Klassen Platform::Collections::Vector
En ändringsbar sekvenssamling.
Vector<T> stöder slumpmässig åtkomst med konstant tid och åtgärder med amorterad konstant tid Append .
Klassen Platform::Collections::VectorView
En skrivskyddad version av en Vector.
Klassen Platform::Collections::InputIterator
En STL-inmatningsiterator som uppfyller kraven för en STL-inmatningsiterator.
Klassen Platform::Collections::VectorIterator
En STL-iterator som uppfyller kraven för en muterbar random-access-iterator i STL.
Klassen Platform::Collections::VectorViewIterator
En STL-iterator som uppfyller kraven för en STL-const iterator med slumpmässig åtkomst.
funktionerna begin() och end()
För att förenkla användningen av STL för att bearbeta
I följande tabell visas tillgängliga iteratorer och funktioner.
| Iterators | Functions |
|---|---|
Platform::Collections::VectorIterator<T>(Lagrar internt Windows::Foundation::Collections::IVector<T> och int.) |
begin
/
end(Windows::Foundation::Collections::IVector<T>) |
Platform::Collections::VectorViewIterator<T>(Lagrar IVectorView<T>^ och int.) internt |
begin
/
end (IVectorView<T>^) |
Platform::Collections::InputIterator<T>(Lagrar IIterator<T>^ och T.) internt |
begin
/
end (IIterable<T>) |
Platform::Collections::InputIterator<IKeyValuePair<K, V>^>(Lagrar IIterator<T>^ och T.) internt |
begin
/
end (IMap<K,V>) |
Platform::Collections::InputIterator<IKeyValuePair<K, V>^>(Lagrar IIterator<T>^ och T.) internt |
begin
/
end (Windows::Foundation::Collections::IMapView) |
Ändringshändelser för samling
Vector och Map stöder databindning i XAML-samlingar genom att implementera händelser som inträffar när ett samlingsobjekt ändras eller återställs, eller när något element i en samling infogas, tas bort eller ändras. Du kan skriva egna typer som stöder databindning, även om du inte kan ärva från Map eller Vector eftersom dessa typer är förseglade.
Delegaterna Windows::Foundation::Collections::VectorChangedEventHandler och Windows::Foundation::Collections::MapChangedEventHandler specificerar signaturer för händelsehanterare för samlingsändringshändelser. Den Windows::Foundation::Collections::CollectionChange offentliga enum klassen och Platform::Collections::Details::MapChangedEventArgs och Platform::Collections::Details::VectorChangedEventArgs ref klasserna lagrar händelseargumenten för att avgöra vad som orsakade händelsen. De *EventArgs typerna definieras i namnområdet Details eftersom du inte behöver konstruera eller använda dem explicit när du använder Map eller Vector.
Se även
typsystem
C++/CX-språkreferens
referens för namnområden