C++20 introduced std::span, which is a view-like object that can take in a continuous sequence, such as a C-style array, std::array, and std::vector. A common problem with a C-style array is it will decay to a pointer when passing to a function. Such a 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 type. 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*'
}
Is this the correct behavior? If so, is there a way to accept a C-style array with span<T>?