I have the following code, which I expected to work, but it doesn't:
#include <array>
#include <span>
void foo(std::span<int>);
int main() {
foo(std::array<int, 3>{});
}
clang fails to compile this:
<source>:7:5: error: no matching function for call to 'foo'
7 | foo(std::array<int, 3>{});
| ^~~
<source>:4:6: note: candidate function not viable: no known conversion from 'std::array<int, 3>' to 'std::span<int>' for 1st argument
4 | void foo(std::span<int>);
| ^ ~~~~~~~~~~~~~~
I expected this to call the constructor:
template< class U, std::size_t N > constexpr span( const std::array<U, N>& arr ) noexcept; // (6)
4-6) Constructs a span that is a view over the array arr; the resulting span has
size() == N
anddata() == std::data(arr)
.These overloads participate in overload resolution only if
extent == std::dynamic_extent || N == extent
istrue
and the conversion fromstd::remove_pointer_t<decltype(data(arr))>
toelement_type
is at most a qualification conversion.
See std::span::span
on cppreference
Why are the constraints of this constructor not satisfied?
extent == std::dynamic_extent
for a std::span<int>
, so the first requirement is obviously metstd::remove_pointer_t<decltype(data(arr))>
is int
, which is equal to std::span<int>::element_type = int
, so the second requirement is also metI don't see any reason why I wouldn't be able to call this constructor.
Qualification conversions can only make something more const qualified.
decltype(data(arr))
is const int*
for const std::array<int, 3>&
. const int
can not be converted to int
via a qualification conversion.
std::span<const int>(std::array<int, 3>{})
does work however (const int
-> const int
).