如何传递空跨度对象?

How to pass an empty span object?

有没有办法将空 std::span<int> 传递给函数?

我有如下功能:

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 ) ) };

我想将其更改为使用 std::span 而不是 std::vector 以便它也可以获得 std::array 原始数组 作为它的论点。

现在在这里:

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?

std::span 是否也正确支持所有连续的容器(例如 std::vectorstd::array 等)?

std::span 的默认构造函数是 documented 为:

constexpr span() noexcept;

Constructs an empty span whose data() == nullptr and size() == 0.

因此,传递默认构造的 std::span<int>() 是明确定义的。调用 empty() 保证 return true.


Does std::span properly support all contiguous containers (e.g. std::vector, std::array, etc.)?

基本上,std::span 可以由任何模拟连续和大小范围的东西构造:

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) and data() == std::ranges::data(range).

特别是,std::vector 确实满足这些要求。

对于 C 风格的数组和 std::array 有特殊的构造函数(以利用它们的编译时大小):

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 has size() == N and data() == std::data(arr).