Передача параметров в проецируемые API

Для определенных типов C++/WinRT предоставляет альтернативные методы для передачи параметра в проецируемый API. Эти классы, принимающие параметры, размещены в пространстве имен winrt::param. Для использования этих классов следует использовать только созданный код C++/WinRT; Не используйте их в собственных функциях и методах.

Это важно

Не следует напрямую использовать типы в пространстве имен winrt::param. Они служат на благо проецирования.

Некоторые из этих альтернатив различают синхронные и асинхронные вызовы. Версия асинхронных вызовов обычно владеет данными параметра, чтобы гарантировать, что значения остаются допустимыми и неизменными до завершения асинхронного вызова. Обратите внимание, однако, что эта защита не распространяется на изменения в коллекции из другого потока. Предотвращение этого является вашей ответственностью.

Альтернативные варианты строковых параметров

winrt::param::hstring упрощает передачу параметров как winrt::hstring. Помимо winrt::hstring, эти альтернативные варианты также принимаются:

Альтернатива Notes
{} Пустая строка.
std::wstring_view За представлением должен следовать терминатор NULL.
std::wstring
wchar_t const* Строка, завершаемая значением NULL.

Нельзя передавать nullptr для представления пустой строки. Вместо этого используйте L"" или {}.

Компилятор умеет вычислять wcslen для строковых литералов во время компиляции. Итак, для литералов L"Name"sv и L"Name" эквивалентны.

Обратите внимание, что объекты std::wstring_view не завершаются значением NULL, но C++/WinRT требует, чтобы символ после окончания представления был null. Если передать объект std::wstring_view, не оканчивающийся нулевым символом, процесс будет завершён.

Альтернативные варианты для итерируемых параметров

winrt::param::iterable<T> и winrt::param::async_iterable<T> упрощают передачу параметров в виде IIterable<T>.

Коллекции среда выполнения Windows IVector<T> и IVectorView<T> уже поддерживают IIterable<T>. Коллекции среда выполнения Windows IMap<K, V> и IMapView<K, V> уже поддерживают IIterable<IKeyValuePair<K, V>>.

Помимо IIterable<T>, также принимаются следующие альтернативные варианты. Обратите внимание, что некоторые альтернативные варианты доступны только для синхронных методов.

Альтернатива Sync Асинхронный режим Notes
std::vector<T> const& Yes No
std::vector<T>&& Yes Yes Содержимое перемещается во временный итерируемый объект.
std::initializer_list<T> Yes Yes Асинхронная версия копирует элементы.
std::initializer_list<U> Yes No U должен быть преобразован в T.
{ begin, end } Yes No begin и end должны быть итераторами прямого прохода, а *begin должен быть приводим к T.

Двойный итератор работает чаще всего в случае, когда у вас есть коллекция, которая не соответствует любому из приведенных выше сценариев, если вы можете выполнить итерацию по нему и создать вещи, которые можно преобразовать в T. Например, у вас может быть IVector<U> или std::vector<U>, где U преобразуется в T.

В следующем примере метод SetStorageItems ожидает IIterable<IStorageItem>. Паттерн двойного итератора даёт возможность передавать другие типы коллекций.

// IVector of derived types.
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Storage::StorageFile>
    storageFiles{ /* initialization elided */ };
dataPackage.SetStorageItems(storageFiles); // doesn't work
dataPackage.SetStorageItems({ storageFiles.begin(), storageFiles.end() }); // works

// Array of derived types.
std::array<winrt::Windows::Storage::StorageFile, 3>
    storageFiles{ /* initialization elided */ };
dataPackage.SetStorageItems(storageFiles); // doesn't work
dataPackage.SetStorageItems({ storageFiles.begin(), storageFiles.end() }); // works

В случае IIterable<IKeyValuePair<K, V>>, принимаются следующие варианты. Обратите внимание, что некоторые альтернативные варианты доступны только для синхронных методов.

Альтернатива Sync Асинхронный режим Notes
std::map<K, V> const& Yes No
std::map<K, V>&& Yes Yes Содержимое перемещается во временный итерируемый объект.
std::unordered_map<K, V> const& Yes No
std::unordered_map<K, V>&& Yes Yes Содержимое перемещается во временный итерируемый объект.
std::initializer_list<std::pair<K, V>> Yes Yes Асинхронная версия копирует список во временный итерируемый объект.
{ begin, end } Yes No begin и end должны быть прямыми итераторами, а begin->first и begin->second должны быть приводимы к K и V соответственно.

Альтернативные варианты для параметров представления векторов

winrt::param::vector_view<T> и winrt::param::async_vector_view<T> упрощают передачу параметров в виде IVectorView<T>.

Вы можете вызвать IVector<T>::GetView, чтобы получить IVectorView<T> из IVector<T>.

Помимо IVectorView<T>, также принимаются следующие альтернативные варианты. Обратите внимание, что некоторые альтернативные варианты доступны только для синхронных методов.

Альтернатива Sync Асинхронный режим Notes
std::vector<T> const& Yes No
std::vector<T>&& Yes Yes Содержимое перемещается во временный режим просмотра.
std::initializer_list<T> Yes Yes Асинхронная версия копирует список во временное представление.
{ begin, end } Yes No begin и end должны быть итераторами прямого прохода, а *begin должен быть приводим к T.

Опять же, версию двойного итератора можно использовать для создания векторных представлений из вещей, которые не соответствуют существующей альтернативе. Временное представление более эффективно, если итераторы begin и end являются итераторами случайного доступа.

Альтернативные варианты для параметров представления карты

winrt::param::map_view<T> и winrt::param::async_map_view<T> упрощают передачу параметров в виде IMapView<T>.

Вы можете вызвать IMap<K, V>::GetView, чтобы получить IMapView<K, V> из объекта IMap<K, V>.

Помимо IMapView<K, V> также принимаются следующие альтернативные варианты. Обратите внимание, что некоторые альтернативные варианты доступны только для синхронных методов.

Альтернатива Sync Асинхронный режим Notes
std::map<K, V> const& Yes No
std::map<K, V>&& Yes Yes Содержимое перемещено во временное представление.
std::unordered_map<K, V> const& Yes No
std::unordered_map<K, V>&& Yes Yes Содержимое перемещено во временное представление.
std::initializer_list<std::pair<K, V>> Yes Yes Содержимое копируется в временное представление. Ключи могут не дублироваться.

Альтернативные варианты для векторных параметров

winrt::param::vector<T> упрощает передачу параметров в виде IVector<T>. Помимо IVector<T>, эти альтернативные варианты также принимаются:

Альтернатива Notes
std::vector<T>&& Содержимое перемещается во временный вектор. Результаты не перемещаются назад.
std::initializer_list<T>

Если метод мутирует временный вектор, эти изменения не отражаются в исходных параметрах. Чтобы отслеживать изменения, передайте IVector<T>.

Альтернативные варианты параметров карты

winrt::param::map<K, V> упрощает передачу параметров в виде IMap<K, V>. Помимо IMap<K, V>, эти альтернативные варианты также принимаются:

Вы можете передать Notes
std::map<K, V>&& Содержимое перемещается во временную карту. Результаты не переносятся обратно.
std::unordered_map<K, V>&& Содержимое перемещается во временную карту. Результаты не перемещаются обратно.
std::initializer_list<std::pair<K, V>>

Если метод мутирует временную карту, эти изменения не отражаются в исходных параметрах. Чтобы наблюдать за изменениями, передайте IMap<K, V>.

Альтернативные варианты для параметров массива

winrt::array_view<T> не относится к пространству имён winrt::param, но используется для параметров, представляющих собой массивы в стиле C. Помимо явного array_view<T>, эти альтернативные варианты также принимаются:

Альтернатива Notes
{} Пустой массив.
U[] Массив стилей C, в котором U преобразуется в T и sizeof(U) == sizeof(T).
std::array<U, N> Где U преобразуется в T и sizeof(U) == sizeof(T).
std::vector<U> Где U преобразуется в T и sizeof(U) == sizeof(T).
{ begin, end } begin и end должен иметь тип T*, представляющий диапазон [begin, end).
std::initializer_list<T>
std::span<U, N> Где U преобразуется в T и sizeof(U) == sizeof(T).

Также см. запись блога О различных шаблонах передачи массивов стилей C через границу среда выполнения Windows ABI.