title | description | ms.date | f1_keywords | helpviewer_keywords | dev_langs | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
owning_view class (C++ Standard Library) |
API reference for the Standard Template Library (STL) <ranges> owning_view class, which takes ownership of the elements in a range. |
10/05/2022 |
|
|
|
A view that takes ownership of the elements in another range.
template<range R>
requires std::movable<R> && (!is-initializer-list<R>)
class owning_view : public ranges::view_interface<owning_view<R>>;
R
The type of the underlying range.
For a description of the following entries, see View class characteristics
Characteristic | Description |
---|---|
Range adaptor | views::all |
Underlying range | Must satisfy input_range or higher |
Element type | Same as the underlying range |
View iterator category | Same as the underlying range |
Sized | Only if the underlying range satisfies sized_range |
Is const -iterable |
Only if the underlying range satisfies const-iterable |
Common range | Only if the underlying range satisfies common_range |
Borrowed range | Only if the underlying range satisfies borrowed_range |
Member functions | Description |
---|---|
Constructors | Construct an owning_view . |
base C++20 |
Get a reference to the owned range. |
begin C++20 |
Get an iterator to the first element. |
data C++20 |
Get a pointer to the first element. |
empty C++20 |
Test whether the view is empty. |
end C++20 |
Get the sentinel at the end of the view. |
size C++20 |
Get the number of elements. |
operator= |
Assign (move) the contents from another owning_view to this one. |
Inherited from view_interface |
Description |
back C++20 |
Get the last element. |
front C++20 |
Get the first element. |
operator[] C++20 |
Get the element at the specified position. |
operator bool C++20 |
Test whether the view isn't empty. |
The best way to create an owning_view
is by using the views::all
range adaptor. Range adaptors are the intended way to create view classes. The view types are exposed in case you want to create your own custom view type.
Even though this class owns its elements, it's not expensive to construct because the underlying range is moved using std::move()
.
This view is useful when you want a range that doesn't depend on the lifetime of the container providing the elements.
Header: <ranges>
(since C++20)
Namespace: std::ranges
Compiler Option: /std:c++20
or later is required.
Create an instance of a 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
The range to move to the owning_view
.
v
The owning_view
to move to the new owning_view
.
For information about template parameter types, see Template parameters.
1) The default constructor creates a default-initialized owning_view
.
2) Move constructs the owning_view
from rg
.
3) An owning_view
can't be copied, only moved.
4) Construct the owning_view
from another 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
Gets a reference to the underlying range.
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_); }
None.
A reference to the underlying range, call it rg
.
For 1 & 2, the underlying range is returned via return rg;
For 3 & 4, the underlying range is returned via std::move(rg);
Get an iterator to the first element in the view.
constexpr iterator_t<R> begin();
constexpr auto begin() const requires range<const R>;
None.
An iterator pointing at the first element in the view:
:::image type="content" source="media/begin-end-sentinel.png" alt-text="Picture of a vector with the elements 10, 20, and 30. The first element contains 10 and is labeled begin(). The last element contains 30 and is labeled 'last element'. An imaginary box after the last element indicates the sentinel and is labeled end().":::
Get a pointer to the first element in the view.
constexpr auto data()
requires std::contiguous_iterator<ranges::iterator_t<R>>;
constexpr auto data() const
requires std::contiguous_iterator<ranges::iterator_t<const R>>;
None.
A pointer to the first element in the view.
The underlying owned range must satisfy contiguous_range
.
Test whether the view is empty.
constexpr bool empty();
constexpr bool empty() const;
None.
Returns true
if the underlying range has no elements. Otherwise, returns false
.
Get the sentinel at the end of the view.
constexpr sentinel_t<R> end();
constexpr auto end() const requires range<const R>
The sentinel that follows the last element in the view:
:::image type="content" source="media/begin-end-sentinel.png" alt-text="Picture of a vector with the elements 10, 20, and 30. The first element contains 10 and is labeled begin(). The last element contains 30 and is labeled 'last element'. An imaginary box after the last element indicates the sentinel and is labeled end().":::
Get the number of elements in the view.
constexpr auto size() requires ranges::sized_range<R>;
constexpr auto size() const requires ranges::sized_range<const R>;
None.
The number of elements in the view.
Assign (move) the contents from another owning_view
to this one.
owning_view& operator=(owning_view&&) = default;
The owning_view
to assign (move) to this one.
*this
An owning_view
can't be copied, only moved.
// 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