I'd like to be able to pass my custom container this std::span
constructor:
template< class R >
explicit(extent != std::dynamic_extent)
constexpr span( R&& range );
What do I need to add to my custom class to make it satisfy the requirements to be able to pass it to the std::span
constructor that receives a range?
For example, with std::vector
we are able to do this:
std::vector<int> v = {1, 2, 3};
auto span = std::span{v};
I've already added these to my custom 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;
}
...which in turn allowed me to use range-based loops, and std::data(my_container)
as well as std::size(my_container)
. What am I missing to make it so that I can also pass my container to the std::span
constructor? Does it require to implement a more complex iterator?
CodePudding user response:
This is because your Container
does not satisfy contiguous_range
, which is defined as:
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>>>;
};
In the requires
clause, the return type of ranges::data(t)
is const Type*
, which is different from add_pointer_t<range_reference_t<T>>
that is Type*
.
The workaround is adding a non-const
data()
to your Container
which return Type*
:
Type* data() { return m_Data; }