Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
A C++/CX programokban ingyenesen használhatja a Standard Sablontár (STL) tárolókat vagy bármely más felhasználó által definiált gyűjteménytípust. Ha azonban a gyűjteményeket oda-vissza továbbítja a Windows futtatókörnyezeti alkalmazás bináris interfészén (ABI) keresztül – például egy XAML-vezérlőnek vagy egy JavaScript-ügyfélnek –, windowsos futtatókörnyezet-gyűjteménytípusokat kell használnia.
A Windows futtatókörnyezet határozza meg a gyűjtemények és a kapcsolódó típusok felületeit, a C++/CX pedig a collection.h fejlécfájlban található konkrét C++ implementációkat biztosítja. Ez az ábra a gyűjteménytípusok közötti kapcsolatokat mutatja be:
Az
Platform::Collections::Vectorosztály hasonlít az osztályrastd::vector.Az
Platform::Collections::Maposztály hasonlít az osztályrastd::map.Platform::Collections::VectorViewosztály ésPlatform::Collections::MapViewosztály írásvédett verziói aVectorésMapelemeknek.Az iterátorok a
Platform::Collectionsnévtérben vannak definiálva. Ezek az iterátorok megfelelnek az STL iterátorokra vonatkozó követelményeknek, és lehetővé teszik a ,std::findés más STL-algoritmusok használatátstd::count_ifbármilyenWindows::Foundation::Collectionsinterfésztípuson vagyPlatform::Collectionskonkrét típuson. Ez azt jelenti például, hogy egy C# nyelven létrehozott Windows-futtatókörnyezeti összetevőben iterálhat egy gyűjteményt, és stL-algoritmust alkalmazhat rá.Important
A proxy iterátorok
VectorIteratorésVectorViewIteratorhasználnak proxyobjektumokatVectorProxy<T>ésArrowProxy<T>az STL-tárolókkal való használat engedélyezéséhez. További információ: VectorProxy elemek a cikk későbbi részében.A C++/CX gyűjteménytípusok ugyanazokat a szálbiztonsági garanciákat támogatják, amelyeket az STL-tárolók támogatnak.
Windows::Foundation::Collections::IObservableVectorésWindows::Foundation::Collections::IObservableMapdefiniálhatja azokat az eseményeket, amelyek akkor aktiválódnak, amikor a gyűjtemény különböző módokon változik. Ezen felületek implementálásával aPlatform::Collections::Mapés aPlatform::Collections::Vectortámogatják az XAML-gyűjteményekkel való adatkötést. Ha például rendelkezik egyVector-val, amely adathoz kötött aGrid-hez, amikor elemet ad hozzá egy gyűjteményhez, a változás a Grid UI-ban jelenik meg.
Vektorhasználat
Ha az osztálynak át kell adnia egy szekvenciatárolót egy másik Windows Futtatókörnyezet-összetevőnek, használja Windows::Foundation::Collections::IVector<T> paraméterként vagy visszatérési típusként, valamint Platform::Collections::Vector<T> konkrét megvalósításként. Ha egy nyilvános visszatérési értékben vagy paraméterben Vector típust próbál használni, C3986-os fordítóhiba lép fel. A hiba kijavításához módosítsa a Vector-t egy IVector-re.
Important
Ha a saját programon belül ad át egy sorozatot, akkor használja Vector vagy std::vector, mert hatékonyabbak, mint IVector. Csak akkor használja a IVector-t, ha egy tárolót átvisz az ABI-n.
A Windows futtatókörnyezet típusú rendszer nem támogatja a szaggatott tömbök fogalmát, ezért nem adhat át IVector<Platform::Array<T>> visszatérési értékként vagy metódusparaméterként. Ha át szeretne adni egy szaggatott tömböt vagy sorozatsorozatot az ABI-n, használja a IVector<IVector<T>^>.
Vector<T> biztosítja a gyűjtemény elemeinek hozzáadásához, eltávolításához és eléréséhez szükséges metódusokat, és implicit módon átalakítható IVector<T>. STL-algoritmusokat is használhat a Vector<T>példányain. Az alábbi példa néhány alapszintű használatot mutat be. A begin függvény és end a függvény itt a Platform::Collections névtérből származik, nem a std névtérből.
#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();
}
Ha már rendelkezik olyan kóddal, amely std::vector használ, és egy Windows futtatókörnyezeti összetevőben szeretné újra felhasználni, használja az egyik Vector konstruktort, amely egy std::vector vagy egy iterátorpárot használ egy Vector létrehozására azon a ponton, ahol a gyűjteményt az ABI-n keresztül továbbítja. Az alábbi példa bemutatja, hogyan használható a Vector mozgató konstruktor egy std::vectorhatékony inicializálásához. Az áthelyezési művelet után az eredeti vec változó már nem érvényes.
//#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));
}
Ha van egy sztringek vektora, amelyet egy későbbi időpontban át kell adni az ABI-n keresztül, el kell döntenie, hogy a sztringeket eleve std::wstring vagy Platform::String^ típusként hozza-e létre. Ha sok feldolgozást kell végeznie a karakterláncokon, használja a wstring. Ellenkező esetben hozza létre a karakterláncokat Platform::String^ típusként, és kerülje a későbbi átalakítás költségét. Azt is el kell döntenie, hogy ezeket a karakterláncokat belsőleg egy std::vector vagy Platform::Collections::Vector-ba helyezi-e el. Általános gyakorlatként használja a(z) std::vector-t, és csak akkor hozzon létre belőle egy Platform::Vector-et, amikor a tárolót átengedi az ABI felületén.
Értéktípusok a Vektorban
A tárolt Platform::Collections::Vector elemeknek implicit módon vagy egy ön által megadott egyéni std::equal_to összehasonlító használatával támogatniuk kell az egyenlőségi összehasonlítást. Minden referenciatípus és minden skaláris típus implicit módon támogatja az egyenlőség összehasonlítását. Nem skaláris értéktípusok, például Windows::Foundation::DateTimeegyéni összehasonlítások esetén – például objA->UniqueID == objB->UniqueID– meg kell adnia egy egyéni függvényobjektumot.
VectorProxy-elemek
Platform::Collections::VectorIterator és Platform::Collections::VectorViewIterator lehetővé teszi a range for hurkok és olyan algoritmusok használatát, mint a std::sort egy IVector<T> tárolóval. Az elemeket azonban IVector nem lehet elérni C++ mutató dereferálásával; csak a GetAt és SetAt metódusokkal érhetők el. Ezért ezek az iterátorok Platform::Details::VectorProxy<T> és Platform::Details::ArrowProxy<T> proxy osztályokat használják, hogy az egyes elemekhez hozzáférést biztosítsanak *, -> és [] operátorokon keresztül, ahogy azt a Standard Library megköveteli. Szigorúan véve, ha adott egy IVector<Person^> vec, akkor a *begin(vec) típusa VectorProxy<Person^>. A proxyobjektum azonban szinte mindig átlátható a kód számára. Ezek a proxyobjektumok nincsenek dokumentálva, mert csak belső használatra szolgálnak az iterátorok, de hasznos tudni, hogyan működik a mechanizmus.
Ha tartományalapú for hurkot használ IVector tárolókon keresztül, az auto&& lehetővé teszi, hogy az iterátor változó megfelelően kössön a VectorProxy elemekhez. Ha használja auto&, a C4239 fordító figyelmeztetése megjelenik, és VectorProxy szerepel a figyelmeztető szövegben.
Az alábbi ábrán egy range for hurok látható egy IVector<Person^>felett. Figyelje meg, hogy a végrehajtás leállt a 64. sor töréspontján. A QuickWatch ablak azt mutatja, hogy az iterátor változó p valójában egy VectorProxy<Person^>, amelynek van m_v és m_i tagváltozói. Amikor azonban meghívja a GetType ezen a változón, az visszaadja a Person példány p2azonos típusát. A tanulság az, hogy bár VectorProxy és ArrowProxy megjelenhet a Gyorstárban, a hibakeresőben bizonyos fordítói hibák kapcsán vagy más helyeken, általában nincs szükség arra, hogy kifejezetten kódoljunk rájuk.
Az egyik forgatókönyv, amikor a proxyobjektum körül kell kódolnia, az az, amikor egy dynamic_cast kell végrehajtania az elemeken– például amikor egy adott típusú XAML-objektumot keres egy UIElement elemgyűjteményben. Ebben az esetben először az elemet Platform::Object típusra kell konvertálni, majd végre kell hajtani a dinamikus típuskonverziót.
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...
}
}
}
Térkép használata
Ez a példa bemutatja, hogyan szúrhat be elemeket, és hogyan keresheti meg őket egy Platform::Collections::Map-ben, majd adja vissza őket csak olvasható Map típusként.
//#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();
}
A belső térképfunkciók esetében általában a std::map típust részesítse előnyben teljesítménybeli okokból. Ha át kell adnia a tárolót az ABI-n keresztül, hozzon létre egy Platform::Collections::Map a std::map-ből, és adja vissza Map-t Windows::Foundation::Collections::IMap formájában. Ha egy nyilvános visszatérési értékben vagy paraméterben Map típust próbál használni, C3986-os fordítóhiba lép fel. A hiba kijavításához módosítsa a Map-t egy IMap-re. Bizonyos esetekben – például ha nem végez nagy számú keresést vagy beszúrást, és gyakran továbbítja a gyűjteményt az ABI-n keresztül –, előfordulhat, hogy az elejétől kezdve kevésbé költséges Platform::Collections::Map használni, és elkerülni a std::mapkonvertálásának költségeit. Mindenesetre kerülje a keresési és beszúrási műveleteket egy IMap-on, mivel a három típus közül ezek a legrosszabb teljesítményűek. Csak akkor konvertáljon IMap-ra, amikor a tárolót az ABI-n keresztül adja át.
Értéktípusok a Térképben
Az elemek Platform::Collections::Map rendezetten vannak. Minden olyan elemnek, amelyet egy Map adott helyen kell tárolni, támogatnia kell a szigorú gyenge rendezésnél kisebb összehasonlítást, akár implicit módon, akár egy ön által megadott egyéni std::less összehasonlító használatával. A skaláris típusok implicit módon támogatják az összehasonlítást. Nem skaláris értéktípusokhoz, például Windows::Foundation::DateTimevagy egyéni összehasonlításokhoz – például objA->UniqueID < objB->UniqueID– egyéni összehasonlítót kell megadnia.
Gyűjteménytípusok
A gyűjtemények négy kategóriába sorolhatók: a sorozatgyűjtemények és az asszociatív gyűjtemények módosítható és csak olvasható verziói. A C++/CX emellett három olyan iterátorosztály biztosításával javítja a gyűjteményeket, amelyek leegyszerűsítik a gyűjtemények elérését.
A módosítható gyűjtemény elemei módosíthatók, de a csak olvasható gyűjtemények elemei, amelyeket nézetnek neveznek, csak olvashatók. Egy Platform::Collections::Vector vagy Platform::Collections::VectorView gyűjtemény elemei egy iterátor, a gyűjtemény Vector::GetAt vagy egy index használatával érhetők el. Az asszociatív gyűjtemény elemei a gyűjtemény Map::Lookup és egy kulcs használatával érhetők el.
Platform::Collections::Map osztály
Módosítható, asszociatív gyűjtemény. A térképelemek kulcs-érték párok. A kulcsok keresése a társított érték lekéréséhez és az összes kulcs-érték páron keresztüli iteráláshoz egyaránt támogatott.
Map és MapView a <K, V, C = std::less<K>>-n alapulnak, így testre szabhatja az összehasonlítási módszert. Emellett a Vector és a VectorView a <T, E = std::equal_to<T>> sablonra alapulnak, így testre szabhatja a IndexOf()viselkedését. Ez elsősorban az értékstruktúra Vector és VectorView szempontjából fontos. Például egy Vector<Windows::Foundation::DateTime> létrehozásához egyéni összehasonlítót kell megadnia, mert a DateTime nem támogatja a == operátor túlterhelését.
Platform::Collections::MapView osztály
Egy Mapírásvédett verziója.
Platform::Collections::Vector osztály
Módosítható sorozatgyűjtemény.
Vector<T> támogatja az állandó idejű véletlenszerű hozzáférést és az amortizált-állandó-idő Append műveleteket.
Platform::Collections::VectorView osztály
Egy Vectorírásvédett verziója.
Platform::Collections::InputIterator osztály
StL iterátor, amely megfelel az STL bemeneti iterátor követelményeinek.
Platform::Collections::VectorIterator osztály
Egy STL iterátor, amely megfelel egy STL-mutable véletlenszerű hozzáférésű iterátor követelményeinek.
Platform::Collections::VectorViewIterator osztály
StL iterátor, amely megfelel az STL const véletlenszerű hozzáférésű iterátor követelményeinek.
begin() és end() függvények
Az STL használatának megkönnyítése érdekében C++/CX támogatja a VectorView és MapViewWindows::Foundation::Collections, begin, , end és tetszőleges end objektumok feldolgozására.
Az alábbi táblázat az elérhető iterátorokat és függvényeket sorolja fel.
| Iterators | Functions |
|---|---|
Platform::Collections::VectorIterator<T>(Belsőleg tárolja Windows::Foundation::Collections::IVector<T> és int.) |
begin
/
end(Windows::Foundation::Collections::IVector<T>) |
Platform::Collections::VectorViewIterator<T>(Belső tárolók IVectorView<T>: ^ és int.) |
begin
/
end (IVectorView<T>^) |
Platform::Collections::InputIterator<T>(Belső tárolók IIterator<T>: ^ és T.) |
begin
/
end (IIterable<T>) |
Platform::Collections::InputIterator<IKeyValuePair<K, V>^>(Belső tárolók IIterator<T>: ^ és T.) |
begin
/
end (IMap<K,V>) |
Platform::Collections::InputIterator<IKeyValuePair<K, V>^>(Belső tárolók IIterator<T>: ^ és T.) |
begin
/
end (Windows::Foundation::Collections::IMapView) |
Gyűjteményváltozási események
Vector és Map támogatja az XAML-gyűjteményekben való adatkötést olyan események implementálásával, amelyek a gyűjteményobjektumok módosításakor vagy alaphelyzetbe állításakor, illetve a gyűjtemény bármely elemének beszúrása, eltávolítása vagy módosításakor fordulnak elő. Az adatkötést támogató saját típusokat írhat, de nem örökölhet Map vagy Vector, mert ezek a típusok lezárva vannak.
A Windows::Foundation::Collections::VectorChangedEventHandler és Windows::Foundation::Collections::MapChangedEventHandler delegáltak határozzák meg a gyűjteményváltozási eseményekhez tartozó eseménykezelők aláírásait. A Windows::Foundation::Collections::CollectionChange nyilvános enumerálási osztály és Platform::Collections::Details::MapChangedEventArgsPlatform::Collections::Details::VectorChangedEventArgs a ref osztály tárolja az eseményargumentumokat annak meghatározásához, hogy mi okozta az eseményt. A *EventArgs típusok a Details névtérben vannak definiálva, mert nem kell explicit módon létrehoznia vagy felhasználnia őket Map vagy Vectorhasználatakor.
Lásd még
Típus rendszer
C++/CX nyelvi referencia
Névterek – referencia