'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