Как можно преобразовать std::vector в std::span?

#c #c 20

#c #c 20

Вопрос:

В документах по конструкторам std ::span нет ни одного, который принимает std::vector .

Тогда как получается, что этот код (исходная страница) компилируется?

 // 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;
    
}
  

т.е. какой конструктор std::span был вызван в (1)?

Ответ №1:

Это конструктор (7) в наборе перегрузки:

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

Из объяснения:

Создает диапазон, представляющий собой представление в диапазоне r; результирующий диапазон имеет size() == std::ranges::size(r) и data() == std::ranges::data(r) .

Существуют дополнительные ограничения на то, когда эта подпись участвует в разрешении перегрузки, но в этом суть. И std::vector удовлетворяет этим требованиям.

Хорошо, что это поддерживается только настолько ограниченным, насколько это необходимо, потому что это позволяет пользовательским (не std ) контейнерам допускать неявное преобразование в std::span экземпляры.