Is there a way to pass an empty std::span<int>
to a function?
I have a function like below:
bool func( const std::vector<int>& indices )
{
if ( !indices.empty( ) )
{
/* do something */
}
...
}
// when calling it with an empty vector
const bool isAcceptable { func( std::vector<int>( 0 ) ) };
And I want to change it to use std::span
instead of std::vector
so that it can also get std::array
and raw array as its argument.
Now here:
bool func( const std::span<const int> indices )
{
if ( !indices.empty( ) )
{
/* do something */
}
...
}
// when calling it with an empty span
const bool isAcceptable { func( std::span<int>( ) ) }; // Is this valid code?
Also does std::span
properly support all contiguous containers (e.g. std::vector
, std::array
, etc.)?
CodePudding user response:
std::span
's default constuctor is documented as:
constexpr span() noexcept;
Constructs an empty span whose
data() == nullptr
andsize() == 0
.
Hence, passing a default constructed std::span<int>()
is well-defined. Calling empty()
on it is guaranteed to return true
.
Does
std::span
properly support all contiguous containers (e.g.std::vector
,std::array
, etc.)?
Basically, std::span
can be constructed from anything that models a contiguous and sized range:
template<class R> explicit(extent != std::dynamic_extent) constexpr span(R&& range);
Constructs a span that is a view over the range range; the resulting span has
size() == std::ranges::size(range)
anddata() == std::ranges::data(range)
.
In particular, std::vector
does satisfy these requirements.
For C-style arrays and std::array
there are special constructors (to harness their compile-time size):
template<std::size_t N> constexpr span(element_type (&arr)[N]) noexcept; template<class U, std::size_t N> constexpr span(std::array<U, N>& arr) noexcept; template<class U, std::size_t N> constexpr span(const std::array<U, N>& arr) noexcept;
Constructs a span that is a view over the array
arr
; the resulting span hassize() == N
anddata() == std::data(arr)
.