c++templatesc++20template-argument-deductionstd-span

Why can T not be deduced for std::span<T> when passing a std::vector?


In the following C++20 code, passing a std::vector to a templated function with a std::span<T> parameter fails, because obviously the compiler cannot deduce the template parameter. I have tried this with GCC, Clang and MSVC; all fail.

Invoking like this works: f3(std::span(vi)) or f3(std::span(vp)).

I would like to know why this fails, because in my understanding, std::vector is a range, and std::span has a deduction guide for ranges.

#include <memory>
#include <vector>
#include <span>

void f1(std::span<int> s)
{
}

void f2(std::span<std::shared_ptr<int>> s)
{
}

template<typename T>
void f3(std::span<T> s)
{
}

int main(int argc, char* argv[])
{
    std::vector<int> vi;
    std::vector<std::shared_ptr<int>> vp;

    f1(vi);
    f2(vp);
    f3(vi); // ERROR: no matching function for call to 'f3'
    f3(vp); // ERROR: no matching function for call to 'f3'

    return 0;
}

Solution

  • If a function argument participates in template argument deduction, no implicit conversions are allowed for that function argument.