如何使 class 与采用范围的 std::span 构造函数兼容?
How to make class compatible with std::span constructor that takes a range?
我希望能够将我的自定义容器传递给这个 std::span
构造函数:
template< class R >
explicit(extent != std::dynamic_extent)
constexpr span( R&& range );
我需要向我的自定义 class 添加什么才能使其满足能够将其传递给接收范围的 std::span
构造函数的要求?
例如,使用 std::vector
我们可以这样做:
std::vector<int> v = {1, 2, 3};
auto span = std::span{v};
我已经将这些添加到我的自定义 class:
Type* begin()
{
return m_Data;
}
Type* end()
{
return m_Data + m_Length;
}
const Type* data() const
{
return m_Data;
}
size_t size() const
{
return m_Length;
}
...这又允许我使用基于范围的循环,以及 std::data(my_container)
和 std::size(my_container)
。我缺少什么才能将我的容器传递给 std::span
构造函数?是否需要实现更复杂的迭代器?
这是因为你的Container
不满足contiguous_range
,定义为:
template<class T>
concept contiguous_range =
random_access_range<T> && contiguous_iterator<iterator_t<T>> &&
requires(T& t) {
{ ranges::data(t) } -> same_as<add_pointer_t<range_reference_t<T>>>;
};
在requires
子句中,ranges::data(t)
的return类型是const Type*
,不同于add_pointer_t<range_reference_t<T>>
即Type*
.
解决方法是将非 const
data()
添加到您的 Container
which return Type*
:
Type* data() { return m_Data; }
我希望能够将我的自定义容器传递给这个 std::span
构造函数:
template< class R >
explicit(extent != std::dynamic_extent)
constexpr span( R&& range );
我需要向我的自定义 class 添加什么才能使其满足能够将其传递给接收范围的 std::span
构造函数的要求?
例如,使用 std::vector
我们可以这样做:
std::vector<int> v = {1, 2, 3};
auto span = std::span{v};
我已经将这些添加到我的自定义 class:
Type* begin()
{
return m_Data;
}
Type* end()
{
return m_Data + m_Length;
}
const Type* data() const
{
return m_Data;
}
size_t size() const
{
return m_Length;
}
...这又允许我使用基于范围的循环,以及 std::data(my_container)
和 std::size(my_container)
。我缺少什么才能将我的容器传递给 std::span
构造函数?是否需要实现更复杂的迭代器?
这是因为你的Container
不满足contiguous_range
,定义为:
template<class T>
concept contiguous_range =
random_access_range<T> && contiguous_iterator<iterator_t<T>> &&
requires(T& t) {
{ ranges::data(t) } -> same_as<add_pointer_t<range_reference_t<T>>>;
};
在requires
子句中,ranges::data(t)
的return类型是const Type*
,不同于add_pointer_t<range_reference_t<T>>
即Type*
.
解决方法是将非 const
data()
添加到您的 Container
which return Type*
:
Type* data() { return m_Data; }