Leedehai
Leedehai

Reputation: 3950

How can std::vector be converted to std::span?

In the docs on std::span constructors, there isn't one that accepts an std::vector.

Then, how come this code (source page) compiles?

// createSpan.cpp

#include <algorithm>
#include <iostream>
#include <span>
#include <vector>

int main() {

    std::cout << std::endl;
    std::cout << std::boolalpha;

    std::vector myVec{1, 2, 3, 4, 5};
    
    std::span mySpan1{myVec};                                        // (1)
    std::span mySpan2{myVec.data(), myVec.size()};                   // (2)
    
    bool spansEqual = std::equal(mySpan1.begin(), mySpan1.end(),
                                 mySpan2.begin(), mySpan2.end());
    
    std::cout << "mySpan1 == mySpan2: " << spansEqual << std::endl;  // (3)

    std::cout << std::endl;
    
}

i.e. which constructor of std::span was invoked at (1)?

Upvotes: 31

Views: 25738

Answers (1)

lubgr
lubgr

Reputation: 38287

It's constructor (7) in the overload set:

template< class R >
explicit(extent != std::dynamic_extent)
constexpr span( R&& r );

From the explanation:

Constructs a span that is a view over the range r; the resulting span has size() == std::ranges::size(r) and data() == std::ranges::data(r).

There are further restriction on when this signature takes part in overload resolution, but that's the essence. And std::vector satisfies these requirements.

It's a good thing that this is kept only as constrained as necessary, because it allows custom (non-std) containers to allow for implicit conversion to std::span instances.

Upvotes: 33

Related Questions