'Deducing extent when passing std::array to function expecting std::span
I have a function expecting a std::span parameter. This function is called by passing an std::array.
This works fine if the std::span argument is declared with template parameter Extent set to std::dynamic_extent. But if the function is templated on Extent, the compiler is unable to deduce this value from std::array argument.
Any idea why the compiler is unable to deduce this template argument ?
See the snippet code below (Godbolt link).
Update after comments
When we explicitly create a std::span (without specifying template parameters) object when calling g(), everything works fine, the compiler is able to deduce the span type and Extent from the std::array. Following cppreference, the corresponding constructor (5) is not mark as explicit.
So why is the compiler unable to do the same deduction ?
void f(const std::span<std::byte> buffer)
{
std::cout << "f() => Extent = 0x" << std::hex << buffer.extent
<< " Size = " << std::dec << buffer.size() << std::endl;
}
template<std::size_t Extent>
void g(const std::span<std::byte, Extent> buffer)
{
std::cout << "g() => Extent = 0x" << std::hex << buffer.extent
<< " Size = " << std::dec << buffer.size() << std::endl;
}
std::array<std::byte, 4> buffer = {};
f(buffer);
g(std::span{buffer}); // <= Works fine
g(buffer); // <= Compiler error!
With this result from compiler:
<source>:23:6: error: no matching function for call to 'g(std::array<std::byte, 4>&)'
23 | g(buffer);
| ~^~~~~~~~
<source>:13:6: note: candidate: 'template<long unsigned int Extent> void g(std::span<std::byte, _Count>)'
13 | void g(const std::span<std::byte, Extent> buffer)
| ^
<source>:13:6: note: template argument deduction/substitution failed:
<source>:23:6: note: 'std::array<std::byte, 4>' is not derived from 'std::span<std::byte, _Count>'
23 | g(buffer);
| ~^~~~~~~~
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
