Passing c-style array to `span<T>`

  c-style-array, c++, c++20, html

C++20 introduced std::span, which is a view-like object that can takes in a continuous sequence, such as C-style array, std::array, and std::vector. A common problem with C-style array is it will decay to a pointer when passing to a function. Such problem can be solved by using std::span:

size_t size(std::span<int> s)
{
    return s.size();
}

int main()
{
    std::array arr = {1,2,3,4,5};
    std::vector vec = {1,2,3,4,5};
    auto il = {1,2,3,4,5};
    int c_arr[] = {1,2,3,4,5};
    std::cout << size(arr) << size(vec) << size(il) << size(c_arr);
}

This would print 5555, as expected. However, size probably shouldn’t take in only containers of int, instead it should take in containers of any types. However, changing the size to a templated function, that takes in a std::span<T>, it can no longer substitute the C-style array successfully, while the others can:

template<typename T>
size_t size(std::span<T> s)
{
    return s.size();
}

int main()
{
    std::array arr = {1,2,3,4,5};
    std::vector vec = {1,2,3,4,5};
    auto il = {1,2,3,4,5};
    int c_arr[] = {1,2,3,4,5};
    std::cout << size(arr) << size(vec) << size(il) << size(c_arr);
                                                       ^^^^^^^^^^^
    // error: no matching function for call to 'size(int [5])'
    // note: template argument deduction/substitution failed:
    // note: mismatched types 'std::span<_Type, 18446744073709551615>' and 'int*'
}

Godbolt

Is this the correct behavior? If so, is there a way to accept c-style array with span<T>?

Source: Windows Questions C++

LEAVE A COMMENT