owning_view 类(C++ 标准库)

获取另一个区域中元素的所有权的视图。

语法

template<range R>
    requires std::movable<R> && (!is-initializer-list<R>)
class owning_view : public ranges::view_interface<owning_view<R>>;

模板参数

R
基础范围的类型。

视图特征

有关下列条目的说明,请参阅视图类特征

特征 说明
范围适配器 views::all
基础范围 必须满足 input_range 或更高范围
元素类型 与基础范围相同
视图迭代器类别 与基础范围相同
已设置大小 仅当基础范围满足 sized_range 要求时
const 可迭代 仅当基础范围满足 const-iterable 要求时
常见范围 仅当基础范围满足 common_range 要求时
借入范围 仅当基础范围满足 borrowed_range 要求时

成员

成员函数 描述
构造函数 构造 owning_view
baseC++20 获取对自有范围的引用。
beginC++20 获取指向第一个元素的迭代器。
dataC++20 获取指向第一个元素的指针。
emptyC++20 测试视图是否为空。
endC++20 获取视图末尾的 sentinel。
sizeC++20 获取元素数。
operator= 将内容从另一个 owning_view 分配(移动)给此内容。
view_interface 继承 描述
backC++20 获取最后一个元素。
frontC++20 获取第一个元素。
operator[]C++20 获取指定位置的元素。
operator boolC++20 测试视图是否不为空。

注解

创建 owning_view 的最佳方法是使用 views::all 范围适配器。 范围适配器是创建视图类的预期方法。 如果要创建自己的自定义视图类型,会公开视图类型。

尽管此类拥有其元素,但构造成本并不高,因为基础范围是使用 std::move() 移动的。

如果希望某个范围不依赖于提供元素的容器的生存期,则此视图非常有用。

要求

标头: <ranges> (自C++20以来)

命名空间std::ranges

编译器选项:/std:c++20或更高版本是必需的。

构造函数

创建 owning_view的实例。

1) owning_view() requires default_initializable<R> = default;
2) constexpr owning_view(R&& rg); 
3) owning_view(const owning_view& v) = delete; // no copy constructor 
4) owning_view(const owning_view&& v) = default; // move constructor

参数

rg
要移动到 owning_view 的范围。

v
要移动到新 owning_viewowning_view

有关模板参数类型的信息,请参阅模板参数

备注

1) 默认构造函数创建默认初始化 owning_view
2) 移动从 rg 构造 owning_view
3) 无法复制 owning_view,只能移动。
4) 从另一个 owning_view 构造 owning_view

示例: owning_view

// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
#include <utility>

int main()
{
    std::vector<int> v = {1,2,3,4,5,6,7,8,9,10};
    auto myOwningView = std::views::all(std::move(v)); // create an owning_view from a moved vector
    std::cout << v.size() << '\n'; // outputs 0 because myOwningView now owns the elements
    std::cout << myOwningView.size() << '\n'; // outputs 10

    std::vector<int> v2 = {1,2,3,4,5};
    std::ranges::owning_view<std::vector<int>> ov2{std::move(v2)};
    std::cout << v2.size() << '\n'; // outputs 0 because ov2 now owns the elements
    std::cout << ov2.size() << '\n'; // outputs 5
}
0
10
0
5

base

获取对基础范围的引用。

1) constexpr R& base() & noexcept { return r_; }
2) constexpr const R& base() const & noexcept { return r_; }
3) constexpr R&& base() && noexcept { return std::move(r_); }
4) constexpr const R&& base() const && noexcept { return std::move(r_); }

参数

无。

返回值

对基础范围的引用,称之为 rg
对于 1 & 2,基础范围通过 return rg; 返回
对于 3 & 4,基础范围通过 std::move(rg); 返回

begin

获取指向视图中第一个元素的迭代器。

constexpr iterator_t<R> begin();
constexpr auto begin() const requires range<const R>;

参数

无。

返回值

指向视图中第一个元素的迭代器:

包含元素 10、20 和 30 的矢量的图片。第一个元素包含 10,被标记为 begin()。最后一个元素包含 30,被标记为“last element”。最后一个元素之后的虚框指示 sentinel,被标记为 end()。

data

获取指向视图中第一个元素的指针。

constexpr auto data()
    requires std::contiguous_iterator<ranges::iterator_t<R>>;
constexpr auto data() const
    requires std::contiguous_iterator<ranges::iterator_t<const R>>;

参数

无。

返回值

指向视图中第一个元素的指针。

备注

基础拥有的范围必须满足 contiguous_range

empty

测试视图是否为空。

constexpr bool empty();
constexpr bool empty() const;

参数

无。

返回值

如果基础范围没有元素,则返回 true。 否则返回 false

end

获取视图末尾的 sentinel。

constexpr sentinel_t<R> end();
constexpr auto end() const requires range<const R>

返回值

视图中最后一个元素后面的 sentinel:

包含元素 10、20 和 30 的矢量的图片。第一个元素包含 10,被标记为 begin()。最后一个元素包含 30,被标记为“last element”。最后一个元素之后的虚框指示 sentinel,被标记为 end()。

size

获取视图中的元素数。

constexpr auto size() requires ranges::sized_range<R>;
constexpr auto size() const requires ranges::sized_range<const R>;

参数

无。

返回值

视图中的元素数。

operator=

将内容从另一个 owning_view 分配(移动)给此内容。

owning_view& operator=(owning_view&&) = default;

参数

要为此分配(移动)的 owning_view

返回值

*this

注解

无法复制 owning_view,只能移动。

示例: operator=

// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v1 = {1,2,3};
    std::ranges::owning_view<std::vector<int>> ov1{std::move(v1)};
    
    std::vector<int> v2 = {4,5,6};
    std::ranges::owning_view<std::vector<int>> ov2{std::move(v2)};
    
    // operator=
    ov2 = std::move(ov1);

    // ov1 took ownership of v1, so v1 is empty
    // ov2 took ownership of v2, so v2 is empty
    // ov2 then took ownership of ov1, so ov1 is empty
    // ov2 now owns the elements 1, 2, 3

    std::cout << std::boolalpha << "v1.empty():" << v1.empty() << " ov1.empty():" << ov1.empty() << '\n'; // v1.empty():true ov1.empty():true
    std::cout << "v2.empty():" << v2.empty() << " ov2.size():" << ov2.size() << '\n'; // v2.empty():true ov2.size():3

    for (auto e : ov2)
    {
         std::cout << e << ' '; // 1 2 3
    }
}
v1.empty():true ov1.empty():true
v2.empty():true ov2.size():3
1 2 3

另请参阅

<ranges>
all 范围适配器
视图类