对于某些类型,C++/WinRT 提供了将参数传递给投影 API 的替代方法。 这些参数接受类放置在 winrt::p aram 命名空间中。 只有 C++/WinRT 生成的代码才应使用这些类;请勿在自己的函数和方法中使用它们。
Important
不应自行使用 winrt::param 命名空间中的类型。 这是为了提升投影效果。
其中一些替代方法区分同步调用和异步调用。 异步调用的版本通常获取参数数据的所有权,以确保值在异步调用完成之前保持有效且保持不变。 但是,请注意,这种保护并不适用于来自另一个线程对该集合所做的更改。 防止这是你的责任。
字符串参数的替代项
winrt::param::hstring 简化了以 winrt::hstring 形式传递参数。 除了 winrt::hstring 之外,还接受以下替代项:
| 备选方案 | Notes |
|---|---|
{} |
空字符串。 |
| std::wstring_view | 该视图后面必须有一个空终止符。 |
| std::wstring | |
| wchar_t const* | 以 null 结尾的字符串。 |
不能传递 nullptr 来表示空字符串。 请改用 L"" 或 {}。
编译器知道如何在编译时对字符串文本进行评估 wcslen 。 因此,对于文本, L"Name"sv 是 L"Name" 等效的。
请注意, std::wstring_view 对象不是以 null 结尾的,但 C++/WinRT 要求视图末尾后的字符为 null。 如果传递一个未以 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>,以下替代项也同样可接受。 请注意,某些替代方法仅适用于同步方法。
| 备选方案 | 同步 | 异步 | 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>> 的情况,接受以下替代方法。 请注意,某些替代方法仅适用于同步方法。
| 备选方案 | 同步 | 异步 | 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->firstbegin->second必须分别转换为 K 和 V。 |
矢量视图参数的替代项
winrt::param::vector_view<T> 和 winrt::param::async_vector_view<T> 简化了将参数作为 IVectorView<T> 传递。
可以调用 IVector<T>::GetView 从 IVector<T> 获取 IVectorView<T>。
除了 IVectorView<T> 之外,还接受以下替代项。 请注意,某些替代方法仅适用于同步方法。
| 备选方案 | 同步 | 异步 | 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。 |
同样,双迭代器版本可用于根据不适合现有替代项的内容创建向量视图。
如果beginend迭代器是随机访问迭代器,则临时视图更高效。
地图视图参数的替代方法
winrt::param::map_view<T> 和 winrt::param::async_map_view<T> 简化了将参数作为 IMapView<T> 传递。
可以调用 IMap<K, V>::GetView 从 IMap<K, V> 获取 IMapView<K, V>。
除了 IMapView<K、V> 之外,还接受以下替代项。 请注意,某些替代方法仅适用于同步方法。
| 备选方案 | 同步 | 异步 | 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::p aram 命名空间中,但它用于 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)。 |