将参数传递给投影 API

对于某些类型,C++/WinRT 提供了将参数传递到投影 API 的替代方法。 这些接受参数的类放置在 winrt::param 命名空间中。 仅 C++/WinRT 生成的代码应使用这些类;请勿在自己的函数和方法中使用它们。

重要

不应自行使用 winrt::param 命名空间中的类型。 它们的用途是为投影提供帮助。

其中一些替代项区分同步调用和异步调用。 异步调用的版本通常获取参数数据的所有权,以确保值在异步调用完成之前保持有效且保持不变。 但注意,此保护不会扩展到从另一个线程对集合的更改。 防止从另一个线程中转变集合是你的责任。

字符串参数的替代项

winrt::param::hstring 简化了将参数作为 winrt::hstring 传递的过程。 除了 winrt::hstring,还接受以下替代项

替代项 说明
{} 空字符串。
std::wstring_view 视图必须后跟 null 终止符。
std::wstring
wchar_t const* 以 null 终止的字符串。

无法传递 nullptr 来表示空字符串。 请改为使用 L""{}

编译器知道在编译时如何评估字符串文本上的 wcslen。 因此,对于文本,L"Name"svL"Name" 是等效的。

请注意,std::wstring_view 对象不以 null 终止,但 C++/WinRT 要求视图末尾后的字符为 null。 如果你传递并非以 null 终止的 std::wstring_view,则过程将会终止。

可迭代参数的替代方法

winrt::param::iterable<T> 和 winrt::param::async_iterableT< 简化了将参数作为 IIterable>T 传递的过程<>

Windows 运行时集合 IVector<T> 和 IVectorViewT< 已支持 IIterable>T<>。 Windows 运行时集合 IMap<K, V> 和 IMapViewK, V< 已支持 IIterable>IKeyValuePairK, V<<>>

除了 IIterable<T>,还接受以下替代项。 请注意,某些替代项仅适用于同步方法。

替代项 同步 异步 说明
std::vector<T> const&
std::vector<T>&& 内容将移动到临时可迭代对象中。
std::initializer_list<T> 异步版本复制这些项。
std::initializer_list<U> U必须可转换为 T
{ begin, end } beginend 必须为前向迭代器,且 *begin 必须可转换为 T

双迭代器更普遍适用于你有一个不适合以上任何方案的集合的情况,只要你可以循环访问它并生成可以转换为 T 的内容。例如,你可能具有 IVector<U> 或 std::vectorU<,其中 U 可转换为 T>

在以下示例中,SetStorageItems 方法需要 IIterableIStorageItem<>。 使用双迭代器模式,可以传递其他类型的集合。

// 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>>,接受以下替代项。 请注意,某些替代项仅适用于同步方法。

替代项 同步 异步 说明
std::map<K,V> const&
std::map<K, V>&& 内容将移动到临时可迭代对象中。
std::unordered_map<K、V> const&
std::unordered_map<K、V>&& 内容将移动到临时可迭代对象中。
std::initializer_list<std::pair<K、V>> 异步版本将列表复制到临时可迭代对象中。
{ begin, end } beginend 必须为前向迭代器,且 begin->firstbegin->second 必须分别可转换为 K 和 V

矢量视图参数的替代项

winrt::param::vector_view<T> 和 winrt::param::async_vector_viewT< 简化了将参数作为 IVectorView>T 传递的过程<>

可以调用 IVector<T>::GetView 从 IVectorT< 获取 IVectorView>T<>

除了 IVectorView<T>,还接受以下替代项。 请注意,某些替代项仅适用于同步方法。

替代项 同步 异步 说明
std::vector<T> const&
std::vector<T>&& 内容将移动到临时视图中。
std::initializer_list<T> 异步版本将列表复制到临时视图中。
{ begin, end } beginend 必须为前向迭代器,且 *begin 必须可转换为 T

同样,双迭代器版本可用于从那些不适合现有替代项的内容创建矢量视图。 如果 beginend 迭代器是随机访问迭代器,则临时视图更高效。

映射视图参数的替代项

winrt::param::map_view<T> 和 winrt::param::async_map_viewT< 简化了将参数作为 IMapView>T 传递的过程<>

可以调用 IMap<K, V>::GetView,从 IMapK, V< 获取 IMapView>K, V<>

除了 IMapView<K, V>,还接受以下替代项。 请注意,某些替代项仅适用于同步方法。

替代项 同步 异步 说明
std::map<K,V> const&
std::map<K, V>&& 内容将移动到临时视图中。
std::unordered_map<K、V> const&
std::unordered_map<K、V>&& 内容将移动到临时视图中。
std::initializer_list<std::pair<K、V>> 内容将复制到临时视图中。 键不能重复。

矢量参数的替代项

winrt::param::vector<T> 简化了将参数作为 IVectorT< 传递的过程>。 除了 IVector<T>,还接受以下替代项

替代项 说明
std::vector<T>&& 内容将移动到临时矢量中。 结果不会移回
std::initializer_list<T>

如果该方法改变了临时矢量,则这些更改不会反映在原始参数中。 若要观察更改,请传递 IVector<T>

映射参数的替代项

winrt::param::map<K, V> 简化了将参数作为 IMapK, V< 传递的过程>。 除了 IMap<K, V>,还接受以下替代项

可以传递 说明
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>,还接受以下替代项

替代项 说明
{} 空数组。
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 } beginend 的类型必须为 T*,表示范围 [, begin]end
std::initializer_list<T>
std::span<U, N> 其中 U 可转换为 T,且 sizeof(U) == sizeof(T)

另请参阅博客文章跨 Windows 运行时 ABI 边界传递 C 样式数组的多种模式