使用 C++/WinRT 的集合

在内部,Windows 运行时集合具有大量复杂的移动部件。 但要将集合对象传递到 Windows 运行时函数,或要实现自己的集合属性和集合类型时,C++/WinRT 中有函数和基类可以提供支持。 这些功能消除复杂性,并节省大量时间和精力上的开销。

IVector 是由元素的任意随机访问集合实现的 Windows 运行时接口。 如果要自己实现 IVector,还需要实现 IIterable、IVectorView 和 IIterator。 即使需要自定义的集合类型,也需要做大量工作。 但如果你在 std::vector(或者 std::map 或 std::unordered_map)中有数据,而你想要做的只是将其传递到 Windows 运行时 API,那么如果可能你会希望避免进行该级别的工作。 要避免是有可能的,因为 C++/WinRT 可以帮助高效地创建集合,且无需花费太多精力。

集合的帮助程序函数

通用集合,空

本节介绍一个场景,在该场景中你希望创建初始为空的集合;然后在创建完毕后将其填充。

若要检索实现通用集合的类型的新对象,可以调用 winrt::single_threaded_vector 函数模板。 该对象作为 IVector 返回,并且它是一个接口,通过它可以调用所返回对象的函数和属性。

若要将以下代码示例直接复制并粘贴到 Windows 控制台应用程序 (C++/WinRT) 项目的主源代码文件中,请先在项目属性中设置“不使用预编译的标头” 。

// main.cpp
#include <winrt/Windows.Foundation.Collections.h>
#include <iostream>
using namespace winrt;int main()
{winrt::init_apartment();Windows::Foundation::Collections::IVector<int> coll{ winrt::single_threaded_vector<int>() };coll.Append(1);coll.Append(2);coll.Append(3);for (auto const& el : coll){std::cout << el << std::endl;}Windows::Foundation::Collections::IVectorView<int> view{ coll.GetView() };
}

如上述代码示例中所示,创建集合之后,你可以追加元素、对它们进行迭代,并且通常可以像处理从 API 接收到的任何 Windows 运行时集合对象那样处理对象。 如果需要集合的不可变视图,则可以调用 IVector::GetView,如下所示。 如上所示的模式(创建和使用集合)适用于想要将数据传入 API 或从 API 获取数据的简单方案。 可以将 IVector 或 IVectorView 传递到预期 IIterable 的任意位置。

在上述代码示例中,调用 winrt::init_apartment 会初始化 Windows 运行时中(默认在多线程单元中)的线程。 该调用还会初始化 COM。

通用集合,从数据准备

本节介绍想要创建并填充集合的场景。

你可以避免上述代码示例中调用“追加”的开销。 你可能已拥有源数据,或者可能更倾向于在创建 Windows 运行时集合对象之前填充源数据。 下面是操作方法。

auto coll1{ winrt::single_threaded_vector<int>({ 1,2,3 }) };std::vector<int> values{ 1,2,3 };
auto coll2{ winrt::single_threaded_vector<int>(std::move(values)) };for (auto const& el : coll2)
{std::cout << el << std::endl;
}

可将包含数据的临时对象传递给 winrt::single_threaded_vector,就像上方传递 coll1 那样。 也可以将 std:: vector(假设不会再次访问)移动到该函数中。 在这两种情况下,都会将右值传递到函数。 这确保编译器能够高效运作并避免复制数据。 如果想要了解有关右值的详细信息,请参阅值类别以及对它们的引用。

如果想要将 XAML 项目控件绑定到集合,则可以执行以下操作。 但要明白,若要正确设置 ItemsControl.ItemsSource 属性,需要将其设置为 IInspectable 的 IVector 类型的值,或 IBindableObservableVector 等互操作性类型的值。

以下是代码示例,它生成适合绑定的类型集合,并向其追加元素。 可在 XAML 项目控件;绑定到 C++/WinRT 集合中查找到此代码的上下文。

auto bookSkus{ winrt::single_threaded_vector<Windows::Foundation::IInspectable>() };
bookSkus.Append(winrt::make<Bookstore::implementation::BookSku>(L"Moby Dick"));

可以从数据创建 Windows 运行时集合,并在集合上准备好视图以便传递给 API,完全无需复制任何内容。

std::vector<float> values{ 0.1f, 0.2f, 0.3f };
Windows::Foundation::Collections::IVectorView<float> view{ winrt::single_threaded_vector(std::move(values)).GetView() };

在上述示例中,我们创建的集合可以绑定到 XAML 项目控件;但是该集合是不可观测的。

可观测集合

若要检索实现可观测集合的类型的新对象,调用具有任何元素类型的 winrt::single_threaded_observable_vector 函数模板。 但要使可观测集合适合绑定到 XAML 项目控件,使用 IInspectable 作为元素类型。

该对象作为 IObservableVector 返回,并且它是一个接口,你(或它绑定到的控件)可以通过它调用所返回对象的函数和属性

auto bookSkus{ winrt::single_threaded_observable_vector<Windows::Foundation::IInspectable>() };

有关将用户界面 (UI) 控件绑定到可观测集合的详细信息和代码示例,请参阅 XAML 项目控件;绑定到 C++/WinRT 集合。

关联集合(映射)

以下是我们介绍的这两个函数的关联集合版本

  • winrt::single_threaded_map 函数模板以 IMap 形式返回不可观测的关联集合。
  • winrt::single_threaded_observable_map 函数模板以 IObservableMap 形式返回可观测的关联集合。

通过向函数传递 std::map 或 std::unordered_map 类型的右值,可以选择为这些集合准备好数据。

auto coll1{winrt::single_threaded_map<winrt::hstring, int>(std::map<winrt::hstring, int>{{ L"AliceBlue", 0xfff0f8ff }, { L"AntiqueWhite", 0xfffaebd7 }})
};std::map<winrt::hstring, int> values{{ L"AliceBlue", 0xfff0f8ff }, { L"AntiqueWhite", 0xfffaebd7 }
};
auto coll2{ winrt::single_threaded_map<winrt::hstring, int>(std::move(values)) };

单线程

这些函数名称中的“单线程”表示它们不支持任何并发性,换言之,它们不是线程安全的。 此处提到的线程与单元无关,因为这些函数所返回的对象都是敏捷的(请参阅 C++/WinRT 中的敏捷对象)。 但是指对象是单线程的。 如果只想跨应用程序二进制接口 (ABI) 以某种方式传递数据,那么这完全合适。

集合的基类

如果想要实现自定义集合以实现完全灵活,最好避免采用这种复杂的方式。 例如,如果没有 C++/WinRT 基类,以下就是自定义矢量视图的外观。

...
using namespace winrt;
using namespace Windows::Foundation::Collections;
...
struct MyVectorView :implements<MyVectorView, IVectorView<float>, IIterable<float>>
{// IVectorViewfloat GetAt(uint32_t const) { ... };uint32_t GetMany(uint32_t, winrt::array_view<float>) const { ... };bool IndexOf(float, uint32_t&) { ... };uint32_t Size() { ... };// IIterableIIterator<float> First() const { ... };
};
...
IVectorView<float> view{ winrt::make<MyVectorView>() };

从 winrt::vector_view_base 结构模板派生自定义矢量视图,并实现 get_container 函数来公开保存数据的容器,这样做要简单得多。

struct MyVectorView2 :implements<MyVectorView2, IVectorView<float>, IIterable<float>>,winrt::vector_view_base<MyVectorView2, float>
{auto& get_container() const noexcept{return m_values;}private:std::vector<float> m_values{ 0.1f, 0.2f, 0.3f };
};

get_container 返回的容器必须提供 winrt::vector_view_base 需要的 begin 和 end 接口。 如上述示例所示,std::vector 支持这一点。 但你可以返回任何满足相同协定的容器,包括自定义容器。

struct MyVectorView3 :implements<MyVectorView3, IVectorView<float>, IIterable<float>>,winrt::vector_view_base<MyVectorView3, float>
{auto get_container() const noexcept{struct container{float const* const first;float const* const last;auto begin() const noexcept{return first;}auto end() const noexcept{return last;}};return container{ m_values.data(), m_values.data() + m_values.size() };}private:std::array<float, 3> m_values{ 0.2f, 0.3f, 0.4f };
};

以下是 C++/WinRT 提供的基类,用于帮助实现自定义集合。

winrt::vector_view_base

请参阅上述代码示例。

winrt::vector_base

struct MyVector :implements<MyVector, IVector<float>, IVectorView<float>, IIterable<float>>,winrt::vector_base<MyVector, float>
{auto& get_container() const noexcept{return m_values;}auto& get_container() noexcept{return m_values;}private:std::vector<float> m_values{ 0.1f, 0.2f, 0.3f };
};

winrt::observable_vector_base

struct MyObservableVector :implements<MyObservableVector, IObservableVector<float>, IVector<float>, IVectorView<float>, IIterable<float>>,winrt::observable_vector_base<MyObservableVector, float>
{auto& get_container() const noexcept{return m_values;}auto& get_container() noexcept{return m_values;}private:std::vector<float> m_values{ 0.1f, 0.2f, 0.3f };
};

winrt::map_view_base

struct MyMapView :implements<MyMapView, IMapView<winrt::hstring, int>, IIterable<IKeyValuePair<winrt::hstring, int>>>,winrt::map_view_base<MyMapView, winrt::hstring, int>
{auto& get_container() const noexcept{return m_values;}private:std::map<winrt::hstring, int> m_values{{ L"AliceBlue", 0xfff0f8ff }, { L"AntiqueWhite", 0xfffaebd7 }};
};

winrt::map_base 

struct MyMap :implements<MyMap, IMap<winrt::hstring, int>, IMapView<winrt::hstring, int>, IIterable<IKeyValuePair<winrt::hstring, int>>>,winrt::map_base<MyMap, winrt::hstring, int>
{auto& get_container() const noexcept{return m_values;}auto& get_container() noexcept{return m_values;}private:std::map<winrt::hstring, int> m_values{{ L"AliceBlue", 0xfff0f8ff }, { L"AntiqueWhite", 0xfffaebd7 }};
};

winrt::observable_map_base

struct MyObservableMap :implements<MyObservableMap, IObservableMap<winrt::hstring, int>, IMap<winrt::hstring, int>, IMapView<winrt::hstring, int>, IIterable<IKeyValuePair<winrt::hstring, int>>>,winrt::observable_map_base<MyObservableMap, winrt::hstring, int>
{auto& get_container() const noexcept{return m_values;}auto& get_container() noexcept{return m_values;}private:std::map<winrt::hstring, int> m_values{{ L"AliceBlue", 0xfff0f8ff }, { L"AntiqueWhite", 0xfffaebd7 }};
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/621464.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

指定GPU无效

今天在进行模型训练的时候遇到这样一个问题&#xff1a;我想要模型在第1块显卡上进行训练&#xff0c;但是不论怎么指定GPU&#xff0c;模型始终是在第0块显卡上进行训练&#xff0c;很是不理解为什么这样&#xff1f; 经过查找资料&#xff0c;发现一个问题&#xff1a;如果在…

Python基础知识:整理14 利用pyecharts生成地图

1 地图可视化的基本使用 from pyecharts.charts import Map from pyecharts.options import VisualMapOpts # 准备地图对象 map Map()# 准备数据 data [("北京市", 8), ("上海市", 99), ("广州省", 199), ("重庆市", 400), ("…

在FFmpeg源码下增加自定义程序

为了了解FFmpeg解码的细节&#xff0c;使用avcodec_send_packet和avcodec_receive_frame组合&#xff0c;写了一个简单的例子&#xff0c;解码video生成yuv文件&#xff0c;比起用FFmpeg跟踪代码要简单很多。 但是问题是在FFmpeg下编译的ffmpeg/ffplay都可以直接跟踪调试&…

什么是RESTful接口风格

开头语&#xff1a; 大家好&#xff01;欢迎来到本篇博客&#xff0c;今天我们将深入讨论RESTful接口风格。RESTful是一种设计风格&#xff0c;用于构建可扩展、可维护的网络服务。本文将为您介绍RESTful的基本概念、设计原则以及实际应用中的一些技巧。 RESTful接口风格分享&…

el-popover设置 :visible 手动关闭弹窗后,无法点击空白处关闭弹窗。

<script setup lang"ts"> import { ref, unref } from "vue"; import { ClickOutside as vClickOutside } from "element-plus";const popoverShow ref(false); //是否显示 const popoverRef ref();/**点击空白处隐藏 */ const onClickO…

DSL查询文档--各种查询

DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1查询所有 结果&#xff1a; 2全文检索&#xff08;full text&#xff09;查询 常见的全文检索查询包括&#xff1a; match查询&#xff1a;单字段查询 multi_match查询&#xff1a;多字段查询&#xff…

.NET开源免费、企业级、可商用内容管理系统 - SSCMS

前言 今天给大家推荐一款基于.NET Core开源、企业级、可商用、能够以最低的成本、最少的人力投入在最短的时间内架设一个功能齐全、性能优异、规模庞大并易于维护的内容管理系统&#xff1a;SSCMS。 系统官方介绍 SSCMS 内容管理系统基于微软 .NET Core 平台开发&#xff0c…

黑马程序员SpringBoot2-开发实用篇

视频连接&#xff1a;开发实用篇-67-手工启动热部署_哔哩哔哩_bilibili 热部署 手动启动热部署 热部署仅包含restart的过程。 自动启动热部署 按CtrlAltShift/打开下列界面。 禁用热部署 配置高级 ConfigurationProperties 宽松绑定/松散绑定 常用计量单位绑定 数据校验 设置…

Android音视频编码(2)

Android本身提供了音视频编解码工具&#xff0c;很多时候是不需要第三方工具的&#xff0c;比如ffmpeg, OpenCV等&#xff0c;在android中引入第三库比较复杂&#xff0c;在Android音视频编码中介绍了如何引入第三方库libpng来进行进行图片处理&#xff0c;同时引入这些第三方库…

JVM内存区域详解,一文弄懂JVM内存【内存分布、回收算法、垃圾回收器】

视频讲解地址 学习文档 一、内存区域 区域描述线程私有如何溢出程序计数器为了线程切换后能恢复到正确的执行位置&#xff0c;每个线程都要有一个独立的程序计数器。✅唯一一个不会内存溢出的地方虚拟机栈1. 每个方法执行的时候&#xff0c;Java虚拟机都会同步创建一个栈帧用于…

获取当前设备的IP

背景&#xff1a; 在本地使用自带webUI的项目时&#xff0c;需要制定webUI的访问地址。 一般本地访问使用&#xff1a;127.0.0.1&#xff0c;配置为可以从其他设备访问时&#xff0c;需要指定当前设备的IP&#xff0c;或者指定为0.0.0.0。 例如&#xff1a;使用locust的时候&a…

【Python学习】Python学习18- 方法OS 文件/目录方法

目录 【Python学习】Python学习17- File方法 前言os.access()语法&#xff1a; os.chdir(path)语法 os.chflags(path, flags)语法 os.chmod(path, mode)os.chown(path, uid, gid)os.chroot(path)os.close(fd)os.unlink(path)os.popen(command[, mode[, bufsize]])os.read(fd, …

Python--循环语句

在 Python 中&#xff0c;循环语句用于重复执行一段代码多次。Python 主要提供了两种类型的循环&#xff1a;for 循环和 while 循环。 1. for 循环 for 循环用于遍历可迭代对象&#xff08;如列表、元组、字典、字符串等&#xff09;中的每个元素&#xff0c;并对每个元素执行…

[NOIP2009 提高组] 潜伏者

一起来交流编程吧【CSDN app】&#xff1a; http://qm.qq.com/cgi-bin/qm/qr?_wv1027&kx9pL9ccIHGKNLE0CWviAqQ_q6HzxomLW&authKeyVslKe623ptw8VRepda%2Bh0Ttr8Ruz8v%2FBW5HpVzyTWU7ECwpHIZpULMj6qIHYZBVb&noverify0&gro [NOIP2009 提高组] 潜伏者 题目描述…

精通业务:资深程序员的核心优势

在IT行业&#xff0c;我们常常听到关于技术实力、项目经验、团队协作等方面的讨论&#xff0c;但有一个重要因素常常被忽视&#xff0c;那就是对业务的了解。 对于资深程序员来说&#xff0c;懂业务和不懂业务之间的区别&#xff0c;犹如一道深邃的鸿沟&#xff0c;决定着他们…

MCS-51---串行通信的特点

目录 一.同步通信和异步通信 1.异步通信 2.同步通信 二.串行通信的方式 1.单工 2.半双工 3.全双工 三.串行通信的速率 四.MCS-51单片机结构 五.串行口的控制 1.串行口控制寄存器(SCON) 2.电源控制寄存器(PCON) 六.波特率的设计 七.串行口的工作方式 1.方式0 2.…

DM数据库安装注意事项

数据库安装注意事项 一、安装前 一些参数需要在数据库创建实例前找用户确认。 参数名参数掩码参数值备注数据页大小PAGE_SIZE32数据文件使用的页大小(缺省使用8K&#xff0c;建议默认&#xff1a;32)&#xff0c;可以为 4K、8K、16K 或 32K 之一&#xff0c;选择的页大小越大…

k8s存储卷之动态

动态pv需要两个组件 1、卷插件&#xff0c;k8s本身支持的动态pv创建不包含NFS&#xff0c;需要声明和安装一个外部插件 Provisioner 存储分配器&#xff0c;动态创建pv&#xff0c;然后根据pvc的请求自动绑定和使用 2、StorageClass&#xff0c;用来定义pv的属性&#xff0c…

选择和训练模型(Machine Learning 研习之十一)

当您看到本文标题时&#xff0c;不禁感叹&#xff0c;总算是到了训练模型这一节了。 是啊&#xff0c;在之前的文章中&#xff0c;我们对数据进行了探索&#xff0c;以及对一个训练集和一个测试集进行了采样&#xff0c;也编写了一个预处理管道来自动清理&#xff0c;准备您的数…

大数据赋能电竞出海企业发展

近几年电竞行业发展迅速&#xff0c;我国单2022年新增近4万家电竞相关企业&#xff0c;竞争十分激烈。中国电竞市场规模在全球占比19%左右&#xff0c;海外有巨大的增量市场&#xff0c;特别是东南亚、中南亚和拉丁美洲是电竞市场增长最快的地区&#xff0c;在2020至2025年期间…