使用 C++/WinRT 的集合

这篇具有很好参考价值的文章主要介绍了使用 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>>
{
    // IVectorView
    float GetAt(uint32_t const) { ... };
    uint32_t GetMany(uint32_t, winrt::array_view<float>) const { ... };
    bool IndexOf(float, uint32_t&) { ... };
    uint32_t Size() { ... };

    // IIterable
    IIterator<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 文章来源地址https://www.toymoban.com/news/detail-790080.html

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

到了这里,关于使用 C++/WinRT 的集合的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【 java 集合】使用迭代器 Iterator 遍历集合

    💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜 📝 个人主页:馆主阿牛🔥 🎉 支持我:点赞👍+收藏⭐️+留言📝 📣 系列专栏:java 小白到高手的蜕变🍁 💬格言:要成为光,因为有怕黑的人!🔥 上两篇文章总结了集合体系以及Collection常用方法,本节我们来

    2024年02月07日
    浏览(53)
  • Python 集合 add()函数使用详解,集合添加元素

    「作者主页」: 士别三日wyx 「作者简介」: CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」: 小白零基础《Python入门到精通》 add() 函数可以给集合 「添加」 元素。 语法 参数 element :(必选)需要添加的元素 返回值 None,没有返回值,

    2024年02月17日
    浏览(45)
  • Python 集合 union()函数使用详解,Python合并集合

    「作者主页」: 士别三日wyx 「作者简介」: CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」: 小白零基础《Python入门到精通》 union() 可以 「合并」 集合 语法 参数 set :(必选)需要合并的集合 返回值 返回一个合并后的新集合 实例:合

    2024年02月16日
    浏览(35)
  • 使用Stream流对集合排序

    有一些业务需要对集合按照一些规则进行排序,本篇介绍如何用Stream()对集合进行升序或者降序操作。 之前只有接触过使用数据库进行排序,有一些情况需要不同的排序结果,如果进行多次查询会多次操作数据库,所以有些地方使用流对集合操作是更好的选择。 Stream 流 - 调

    2024年02月12日
    浏览(60)
  • Python 集合 set的使用

    创建集合使用{xxx} 或 set(), 但是创建空集合只能使用 set(), 空大括号{} 用来创建空的字典。 集合和列表区别: 集合可以去掉重复数据,即只存放不同的元素 集合中的元素是无序的,故不支持下标访问 创建方式不同,列表是用中括号表示,非空集合使用大括号表示。 有点类

    2024年02月12日
    浏览(43)
  • java Collection集合使用笔记

    它是单例集合的最顶层接口,它表示一组对象,这些对象也称之为Collection的元素 JDK不提供此接口任何直接实现,但提供更具体的子接口(如: List 和 Set )实现 创建Collection集合对象的方法: 多态的形式 具体的实现类: ArrayList Iterator迭代器,Collection集合的专用遍历方式 I

    2024年02月11日
    浏览(49)
  • stream流的使用-获取list集合中对象的单个字段list集合,进行累加操作

    场景及代码案例源于实际项目 现存一list集合,其中保存了投资人的信息。 Person (name, age, money rateOfReturn) 其中的money表示投资人现有资产,rateOfReturn表示投资年回报率 需求: 1.计算投资人年龄之和; 2.根据现有资产及投资回报率,计算所有投资人一年后的资产总和; 实体

    2023年04月22日
    浏览(67)
  • 【Collection集合】概述、使用以及常用方法

    1.Collection集合的概述 它是单列集合的顶级接口,它表示一组对象,这些对象也称为Collection的元素 JDK不提供此接口的任何直接实现,它提供更具体地子接口(如set和list)实现 2.创建Collection集合的对象 多态的方式 具体的实现类ArrayList,在java.util包下需要导包 向集合里添加元

    2024年02月08日
    浏览(41)
  • 【Java】Set集合的基本使用

       📝个人主页:哈__ 期待您的关注  ①:add(Object o):向Set集合中添加元素,不允许添加重复数据。 ②:size():返回Set集合中的元素个数 注意:不会按照保存的顺序存储数据(顺序不定),遍历时不能保证下次结果和上次相同。且向HashSet集合中添加元素,HashSet add方法实质是

    2024年04月13日
    浏览(45)
  • 【JavaDS】浅谈集合LinkedList的使用

    ✨ 博客主页: XIN-XIANG荣 ✨ 系列专栏: 【Java实现数据结构】 ✨ 一句短话: 难在坚持,贵在坚持,成在坚持! LinkedList的底层是双向链表结构,由于链表没有将元素存储在连续的空间中,元素存储在单独的节点中,然后通过引用将节点连接起来了,因此在在任意位置插入或者删除元

    2024年02月22日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包