エクスポート (0) 印刷
すべて展開
この記事は翻訳者によって翻訳されたものです。 記事の文章にポインターを重ねると、原文のテキストが表示されます。
訳文
原文

コレクション (C++/CX)

Visual C++ コンポーネント拡張 (C++/CX) プログラムでは、標準テンプレート ライブラリ (STL) コンテナー、または他の任意のユーザー定義コレクション型を自由に使用できます。 ただし、XAML コントロールまたは JavaScript クライアントに渡す場合など、Windows ランタイム アプリケーション バイナリ インターフェイス (ABI) 間で双方向にコレクションを渡す場合は、Windows ランタイム コレクション型を使用する必要があります。

Windows ランタイム はコレクションおよび関連する型のインターフェイスを定義し、C++/CX は collection.h ヘッダー ファイルで具象 C++ 実装を提供します。 この図は、コレクション型間のリレーションシップを示しています。

コレクション型を示す C++/CX 継承ツリー

クラスがシーケンス コンテナーを別の Windows ランタイム コンポーネントに渡すか、Windows::Foundation::Collections:: IVector<T> をパラメーターまたは戻り値の型として使用するか、Platform::Collections::Vector<T> を具象実装として渡す必要がある場合。 パブリックの戻り値またはパラメーターで Vector 型を使用しようとすると、コンパイラ エラー C3986 が発生します。 このエラーは、VectorIVector に変更することで解決できます。

重要 : 重要

独自のプログラム内のシーケンスを渡している場合は、Vectorstd::vector のどちらかを使用します。それらの方が IVector より効率的であるためです。 ABI を介してコンテナーを渡す場合にのみ、IVector を使用します。

Windows ランタイムの型システムは、ジャグ配列の概念をサポートしていないため、IVector<Platform::Array<T>> を戻り値またはメソッド パラメーターとして渡すことはできません。 ABI を通じてジャグ配列またはシーケンスのシーケンスを渡すには、IVector<IVector<T>^> を使用します。

Vector<T> は、コレクションでの項目の追加、削除、およびアクセスに必要なメソッドを提供します。暗黙的に IVector<T> に変換可能です。 Vector<T> のインスタンスで STL アルゴリズム使用することもできます。 次の例は、基本的な使用法をいくつか示しています。 begin 関数end 関数Platform::Collections 名前空間のもので、std 名前空間のものではありません。


#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();
}


std::vector を使用する既存のコードがあり、それを Windows ランタイム コンポーネントで再使用する場合は、std::vector または反復子のペアを取る Vector コンストラクターの 1 つを使用して、ABI を介してコレクションを渡すポイントに Vector を構築します。 次の例は、std::vector からの効率的な初期化のために Vector 移動コンストラクターを使用する方法を示しています。 移動操作の後、元の vec 変数は有効でなくなります。


//#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));
}


今後のいつか、ABI を介して渡す必要がある文字列ベクターがある場合、その文字列を最初に std::wstring 型として作成するのかそれとも Platform::String^ 型として作成するのかを決定する必要があります。 その文字列に対して多くの処理を実行する必要がある場合、wstring を使用します。 それ以外の場合は、文字列を Platform::String^ 型として作成して、後で変換するコストを回避してください。 また、これらの文字列を std:vectorPlatform::Collections::Vector のどちらに内部的に埋め込むのかも決定する必要があります。 一般に、std::vector を使用し、ABI を介してコンテナーを渡す場合にのみ、そこから Platform::Vector を作成します。

Platform::Collections::Vector に格納される要素は、暗黙的にまたは指定したカスタム std::equal_to 比較子を使用するかして、等値比較をサポートする必要があります。 すべての参照型とすべてのスカラー型は、暗黙的に等値比較をサポートしています。 Windows::Foundation::DateTime などの非スカラー値型、またはカスタム比較 (objA->UniqueID == objB->UniqueID など) の場合、カスタム関数オブジェクトを提供する必要があります。

Platform::Collections::VectorIteratorPlatform::Collections::VectorViewIterator は、IVector<T> コンテナーで range for ループや std::sort などのアルゴリズムの使用を有効にします。 ただし、IVector 要素には、C++ ポインターの逆参照を使用してアクセスできません。これらの要素には、GetAt メソッドおよび SetAt メソッドを介してのみアクセスできます。 したがって、これらの反復子は、STL の要求に従って、Platform::Details::VectorProxy<T> プロキシ クラスおよび Platform::Details::ArrowProxy<T> プロキシ クラスを使用して *->[] の各演算子を介した個々の要素へのアクセスを提供します。 厳密には、IVector<Person^> vec が指定されている場合、*begin(vec) の型は VectorProxy<Person^> になります。 ただし、プロキシ オブジェクトは、ほとんどの場合、コードに対して透過的です。 これらのプロキシ オブジェクトは反復子によって内部でのみ使用されるため文書化されませんが、その機構の動作がわかっていると便利です。

IVector コンテナーに対して range for ループを使用する場合は、auto&& を使用して反復子変数が VectorProxy 要素に正しくバインドされるようにします。 auto または auto& を使用すると、コンパイラ警告 C4239 が発生し、警告テキストに VectoryProxy が示されます。

IVector<Person^> に対する range for ループ処理の例を次に示します。 実行が 64 行のブレークポイントで停止していることに注意してください。 [クイック ウォッチ] ウィンドウには、反復子変数 p が実際には m_v メンバー変数と m_i メンバー変数を持つ VectorProxy<Person^> であることが示されています。 ただし、この変数で GetType を呼び出すと、Person インスタンス p2 と同一の型が返されます。 VectorProxyArrowProxy[クイック ウォッチ]、デバッガーの一部のコンパイラ エラー、またはその他の場所に表示される場合でも、通常はそれらについて明示的にコーディングする必要はありません。

範囲ベースの for ループ内にある VectorProxy

プロキシ オブジェクトに関してコーディングする必要があるのは、UIElement 要素コレクションで特定の型の XAML オブジェクトを探している場合など、要素で dynamic_cast を実行する必要がある場合です。 この場合は、最初に Platform::Object^ に要素をキャストし、その後に動的キャストを実行する必要があります。


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...
        }
    }
}

この例では、項目を挿入し、Platform::Collections::Map でルックアップし、Map を読み取り専用の 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();

}


一般に、内部マップ機能については、パフォーマンス上の理由で std::map 型を優先します。 ABI を介してコンテナーを渡す必要がある場合は、std::map から Platform::Collections::Map を構築し、MapWindows::Foundation::Collections::IMap として返します。 パブリックの戻り値またはパラメーターで Map 型を使用しようとすると、コンパイラ エラー C3986 が発生します。 このエラーは、MapIMap に変更することで解決できます。 たとえば、実行するルックアップや挿入の数が多くなく、ABI を介して頻繁にコレクションを渡すなどの場合、最初から Platform::Collections::Map を使用し std::map を変換するコストを回避した方がコストを抑えられることがあります。 どちらの場合も、IMap のルックアップ操作と挿入操作は、3 つの種類で最もパフォーマンスが低いので避けます。 ABI を介してコンテナーを渡すポイントでのみ、IMap に変換します。

Platform::Collections::Map 内の要素は、順序付きです。 Map に格納しようとする要素は、厳密な弱い順序付けに基づき、"より小さい" 比較をサポートする必要があります。このために、暗黙的な比較、または開発者が指定したカスタム比較子 stl::less が使用されます。 スカラー型では、この比較を暗黙的にサポートしています。 Windows::Foundation::DateTime などの非スカラー値型、またはカスタム比較 (objA->UniqueID < objB->UniqueID など) の場合、カスタム比較子を提供する必要があります。

コレクションは、シーケンス コレクションと関連コレクションそれぞれの変更可能バージョンと読み取り専用バージョンという 4 つのカテゴリに分類されます。 さらに、C++/CX は、コレクションのアクセスを簡単にする 3 つの反復子クラスを提供することによりコレクションを拡張します。 反復子の簡単な説明については、「反復子」を参照してください。

変更可能なコレクションの要素は変更できますが、ビューと呼ばれる読み取り専用コレクションの要素は読み取りしか実行できません。 Platform::Collections::Vector コレクションまたは Platform::Collections::VectorView コレクションの要素には、反復子またはコレクションの Vector::GetAt メソッド とインデックスを使用してアクセスできます。 関連コレクションの要素は、コレクションの Map::Lookup メソッド またはキーを使用することによりアクセスできます。

Platform::Collections::Map クラス

変更可能な関連コレクション。 マップ要素は、キーと値のペアです。 キーを検索してその関連付けられた値を取得することと、キーと値のペアをすべて繰り返すことの両方がサポートされています。

MapMapView は、<K, V, C = std::less<K>> で template 宣言されるので、比較子をカスタマイズできます。さらに、VectorVectorView<T, E = std::equal_to<T>> で template 宣言されるので、IndexOf() の動作をカスタマイズできます。 これは、値の構造体の VectorVectorView について特に重要です。 たとえば、Vector<Windows::Foundation::DateTime> を作成するには、カスタム比較子を指定する必要があります。DateTime は == 演算子をオーバーロードしないからです。

Platform::Collections::MapView クラス

Map の読み取り専用バージョン。

Platform::Collections::Vector クラス

変更可能なシーケンス コレクション。 Vector<T> は、定数時間ランダム アクセス操作と償却定数時間の追加操作をサポートしています。

Platform::Collections::VectorView クラス

Vector の読み取り専用バージョン。

Platform::Collections::InputIterator クラス

STL 入力反復子の要件を満たす STL の反復子。

Platform::Collections::VectorIterator クラス

変更可能な STL ランダム アクセス反復子の要件を満たす STL 反復子。

Platform::Collections::VectorViewIterator クラス

STL の const ランダム アクセス反復子の要件を満たす STL 反復子。

Hh700103.collapse_all(ja-jp,VS.120).gifbegin() および end() 関数

STL を使用した VectorVectorViewMapMapView、および任意の Windows::Foundation::Collections オブジェクトの処理を簡単にするために、C++/CX は、begin 関数 および end 関数 非メンバー関数のオーバーロードをサポートしています。

次の表は、使用できる反復子と関数の一覧を示しています。

Hh700103.collapse_all(ja-jp,VS.120).gifコレクション変更イベント

VectorMap は、XAML コレクションでのデータ バインドをサポートしていますが、これは、コレクション オブジェクトが変更またはリセットされたとき、またはコレクションのいずれかの要素が挿入、削除、または変更されたときに発生するイベントを実装することで実現されています。 データ バインドをサポートする独自の型を作成できます。ただし、MapVector から継承することはできません。これらの型はシールされているためです。

Windows::Foundation::Collections::VectorChangedEventHandler デリゲートと Windows::Foundation::Collections::MapChangedEventHandler デリゲートは、コレクション変更イベントのイベント ハンドラーのシグニチャを指定します。 Windows::Foundation::Collections::CollectionChange パブリック列挙型クラス、および Platform::Collection::Details::MapChangedEventArgs ref クラスと Platform::Collections::Details::VectorChangedEventArgs ref クラスは、イベントの原因を判断するためにイベント引数を格納します。 * EventArgs 型は Details 名前空間で定義されますが、これは、MapVector を使用するときには、それらを明示的に作成および利用する必要がないためです。

コミュニティの追加

表示:
© 2014 Microsoft