跳到主要内容

std::span 构造函数

std::span 类可以通过多种不同的方式构造。使用右上角的按钮,方便地使用箭头导航。

注意

std::span 是一个类模板,具有以下类型参数,在构造函数中使用:

公共T

元素的类型。

公共Extent

容器中的元素数量,如果为动态则为std::dynamic_extent

默认构造函数

span();
  • 此构造函数是 constexprnoexcept

默认构造函数。构造一个空的 span,其

  • data() == nullptr
  • size() == 0
重载决议

此重载仅在以下情况下参与重载解析

extent == 0

extent == std::dynamic_extent

复杂度

常数 - O(1)

示例

#include <iostream>
#include <span>

int main() {
// Default constructed span<int>:
std::span<int> s;

std::cout << "s.size(): " << s.size();
}
结果(控制台)
s.size(): 0

迭代器 + 大小构造函数

template< class It >
explicit(extent != std::dynamic_extent)
constexpr span( It first, size_type count );

构造一个 span,它是范围 [ first, first + count ) 的视图。
结果 span 具有

  • data() == std::to_address(first)
  • size() == count
未定义行为

行为未定义

如果

  • [ first, first + count ) 不是有效范围
  • It 不符合contiguous_iterator模型
  • extent != std::dynamic_extentcount != extent
重载决议

此重载仅在以下情况下参与重载解析

复杂度

常数 - O(1)

示例

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

int main() {
std::vector<int> v{1, 2, 3, 4, 5};
std::span<int> s(v.cbegin(), 3);

std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) std::cout << num << ' ';
}
结果(控制台)
s.size(): 3
elems: 1 2 3

基于范围的构造函数(迭代器)

template< class It, class End >
explicit(extent != std::dynamic_extent)
constexpr span( It first, End last );

构造一个 span,它是范围 [ first, last ) 的视图。
结果 span 具有

  • data() == std::to_address(first)
  • size() == last - first
未定义行为

行为未定义

如果

重载决议

此重载仅在以下情况下参与重载解析

复杂度

常数 - O(1)

示例

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

int main() {
std::vector<int> v{1, 2, 3, 4, 5};
std::span<int> s(v.begin() + 1, v.end() - 1);

std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) {
std::cout << num << ' ';
}
}
结果(控制台)
s.size(): 3
elems: 2 3 4

C 数组和std::array 构造函数

// (1)
template< std::size_t N >
constexpr span( std::type_identity_t<element_type> (&arr)[N] ) noexcept;

// (2)
template< class U, std::size_t N >
constexpr span( std::array<U, N>& arr ) noexcept;

// (3)
template< class U, std::size_t N >
constexpr span( const std::array<U, N>& arr ) noexcept;

构造一个 span,它是数组 arr 的视图。
结果 span 具有

  • size() == N
  • data() == std::data(arr)
重载决议

这些重载仅在以下情况下参与重载解析

  • extent == std::dynamic_extentN == extent
  • std::remove_pointer_t<decltype(data(arr))>element_type 的转换最多限定符转换

复杂度

常数 - O(1)

示例

#include <iostream>
#include <array>
#include <span>

template <typename Type, std::size_t Extent>
void present_span(std::span<Type, Extent> s) {
std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) {
std::cout << num << ' ';
}
std::cout << "\n\n";
}

int main() {
int arr[] = {1, 2, 3, 4, 5};
present_span(std::span(arr)); // (1)

std::array<int, 5> arr2 = {6, 7, 8, 9, 10};
present_span(std::span(arr2)); // (2)

const std::array<int, 5> arr3 = {12, 13, 14, 15, 16};
present_span(std::span(arr3)); // (3)
}
结果(控制台)
s.size(): 5
elems: 1 2 3 4 5

s.size(): 5
elems: 6 7 8 9 10

s.size(): 5
elems: 12 13 14 15 16

任意范围构造函数

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

构造一个 span,它是范围 range 的视图。结果 span 具有

  • size() == std::ranges::size(range)
  • data() == std::ranges::data(range)
未定义行为

行为未定义

如果

重载决议

这些重载仅在以下情况下参与重载解析

复杂度

常数 - O(1)

示例

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

template <typename Type, std::size_t Extent>
void present_span(std::span<Type, Extent> s) {
std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) {
std::cout << num << ' ';
}
std::cout << "\n\n";
}

int main() {
std::vector<int> v = {1, 2, 3, 4};
present_span(std::span(v)); // vector is a valid range

struct custom_range {
int* begin() { return arr.data(); }
int* end() { return arr.data() + arr.size(); }

std::vector<int> arr{1, 2, 3};
};

custom_range cr;
present_span(std::span(cr)); // cr is a valid range
}
结果(控制台)
s.size(): 4
elems: 1 2 3 4

s.size(): 3
elems: 1 2 3

转换构造函数

template< class U, std::size_t N >
explicit(extent != std::dynamic_extent && N == std::dynamic_extent)
constexpr span( const std::span<U, N>& source ) noexcept;

从另一个 span 源的转换构造函数。结果 span 具有

  • size() == source.size()
  • data() == source.data()
未定义行为

行为未定义

如果

  • extent != dynamic_extent
  • source.size() != extent
重载决议

这些重载仅在以下情况下参与重载解析

  • 至少以下之一:
    • extent == std::dynamic_extent
    • N == std::dynamic_extent
    • N == extenttrue
  • Uelement_type 的转换最多限定符转换

复杂度

常数 - O(1)

示例

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

template <typename Type, std::size_t Extent>
void present_span(std::span<Type, Extent> s) {
std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) {
std::cout << num << ' ';
}
std::cout << "\n\n";
}

int main() {
std::vector<int> source = { 1, 2, 3, 4, 5 };
std::array<const int, 4> source2 = { 10, 11, 12, 13 };

std::span<int> s1 = source;
std::span<const int> s2 = source2;
present_span(s1);
present_span(s2);

s2 = s1; // converting ctor

present_span(s1);
present_span(s2);
}
结果(控制台)
s.size(): 5
elems: 1 2 3 4 5

s.size(): 4
elems: 10 11 12 13

s.size(): 5
elems: 1 2 3 4 5

s.size(): 5
elems: 1 2 3 4 5

默认复制构造函数

constexpr span( const span& other ) noexcept = default;

默认复制构造函数复制大小和数据指针。结果 span 具有

  • size() == other.size()
  • data() == other.data()

复杂度

常数 - O(1)

示例

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

template <typename Type, std::size_t Extent>
void present_span(std::span<Type, Extent> s) {
std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) {
std::cout << num << ' ';
}
std::cout << "\n\n";
}

int main() {
std::vector<int> source = { 1, 2, 3, 4, 5 };
std::vector<int> source2 = { 5, 4, 3, 2, 1 };

std::span<int> s1 = source;
std::span<int> s2 = source2;
present_span(s1);
present_span(s2);

s2 = s1; // copy ctor

present_span(s1);
present_span(s2);
}
结果(控制台)
s.size(): 5
elems: 1 2 3 4 5

s.size(): 5
elems: 5 4 3 2 1

s.size(): 5
elems: 1 2 3 4 5

s.size(): 5
elems: 1 2 3 4 5
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。

std::span 构造函数

std::span 类可以通过多种不同的方式构造。使用右上角的按钮,方便地使用箭头导航。

注意

std::span 是一个类模板,具有以下类型参数,在构造函数中使用:

公共T

元素的类型。

公共Extent

容器中的元素数量,如果为动态则为std::dynamic_extent

默认构造函数

span();
  • 此构造函数是 constexprnoexcept

默认构造函数。构造一个空的 span,其

  • data() == nullptr
  • size() == 0
重载决议

此重载仅在以下情况下参与重载解析

extent == 0

extent == std::dynamic_extent

复杂度

常数 - O(1)

示例

#include <iostream>
#include <span>

int main() {
// Default constructed span<int>:
std::span<int> s;

std::cout << "s.size(): " << s.size();
}
结果(控制台)
s.size(): 0

迭代器 + 大小构造函数

template< class It >
explicit(extent != std::dynamic_extent)
constexpr span( It first, size_type count );

构造一个 span,它是范围 [ first, first + count ) 的视图。
结果 span 具有

  • data() == std::to_address(first)
  • size() == count
未定义行为

行为未定义

如果

  • [ first, first + count ) 不是有效范围
  • It 不符合contiguous_iterator模型
  • extent != std::dynamic_extentcount != extent
重载决议

此重载仅在以下情况下参与重载解析

复杂度

常数 - O(1)

示例

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

int main() {
std::vector<int> v{1, 2, 3, 4, 5};
std::span<int> s(v.cbegin(), 3);

std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) std::cout << num << ' ';
}
结果(控制台)
s.size(): 3
elems: 1 2 3

基于范围的构造函数(迭代器)

template< class It, class End >
explicit(extent != std::dynamic_extent)
constexpr span( It first, End last );

构造一个 span,它是范围 [ first, last ) 的视图。
结果 span 具有

  • data() == std::to_address(first)
  • size() == last - first
未定义行为

行为未定义

如果

重载决议

此重载仅在以下情况下参与重载解析

复杂度

常数 - O(1)

示例

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

int main() {
std::vector<int> v{1, 2, 3, 4, 5};
std::span<int> s(v.begin() + 1, v.end() - 1);

std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) {
std::cout << num << ' ';
}
}
结果(控制台)
s.size(): 3
elems: 2 3 4

C 数组和std::array 构造函数

// (1)
template< std::size_t N >
constexpr span( std::type_identity_t<element_type> (&arr)[N] ) noexcept;

// (2)
template< class U, std::size_t N >
constexpr span( std::array<U, N>& arr ) noexcept;

// (3)
template< class U, std::size_t N >
constexpr span( const std::array<U, N>& arr ) noexcept;

构造一个 span,它是数组 arr 的视图。
结果 span 具有

  • size() == N
  • data() == std::data(arr)
重载决议

这些重载仅在以下情况下参与重载解析

  • extent == std::dynamic_extentN == extent
  • std::remove_pointer_t<decltype(data(arr))>element_type 的转换最多限定符转换

复杂度

常数 - O(1)

示例

#include <iostream>
#include <array>
#include <span>

template <typename Type, std::size_t Extent>
void present_span(std::span<Type, Extent> s) {
std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) {
std::cout << num << ' ';
}
std::cout << "\n\n";
}

int main() {
int arr[] = {1, 2, 3, 4, 5};
present_span(std::span(arr)); // (1)

std::array<int, 5> arr2 = {6, 7, 8, 9, 10};
present_span(std::span(arr2)); // (2)

const std::array<int, 5> arr3 = {12, 13, 14, 15, 16};
present_span(std::span(arr3)); // (3)
}
结果(控制台)
s.size(): 5
elems: 1 2 3 4 5

s.size(): 5
elems: 6 7 8 9 10

s.size(): 5
elems: 12 13 14 15 16

任意范围构造函数

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

构造一个 span,它是范围 range 的视图。结果 span 具有

  • size() == std::ranges::size(range)
  • data() == std::ranges::data(range)
未定义行为

行为未定义

如果

重载决议

这些重载仅在以下情况下参与重载解析

复杂度

常数 - O(1)

示例

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

template <typename Type, std::size_t Extent>
void present_span(std::span<Type, Extent> s) {
std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) {
std::cout << num << ' ';
}
std::cout << "\n\n";
}

int main() {
std::vector<int> v = {1, 2, 3, 4};
present_span(std::span(v)); // vector is a valid range

struct custom_range {
int* begin() { return arr.data(); }
int* end() { return arr.data() + arr.size(); }

std::vector<int> arr{1, 2, 3};
};

custom_range cr;
present_span(std::span(cr)); // cr is a valid range
}
结果(控制台)
s.size(): 4
elems: 1 2 3 4

s.size(): 3
elems: 1 2 3

转换构造函数

template< class U, std::size_t N >
explicit(extent != std::dynamic_extent && N == std::dynamic_extent)
constexpr span( const std::span<U, N>& source ) noexcept;

从另一个 span 源的转换构造函数。结果 span 具有

  • size() == source.size()
  • data() == source.data()
未定义行为

行为未定义

如果

  • extent != dynamic_extent
  • source.size() != extent
重载决议

这些重载仅在以下情况下参与重载解析

  • 至少以下之一:
    • extent == std::dynamic_extent
    • N == std::dynamic_extent
    • N == extenttrue
  • Uelement_type 的转换最多限定符转换

复杂度

常数 - O(1)

示例

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

template <typename Type, std::size_t Extent>
void present_span(std::span<Type, Extent> s) {
std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) {
std::cout << num << ' ';
}
std::cout << "\n\n";
}

int main() {
std::vector<int> source = { 1, 2, 3, 4, 5 };
std::array<const int, 4> source2 = { 10, 11, 12, 13 };

std::span<int> s1 = source;
std::span<const int> s2 = source2;
present_span(s1);
present_span(s2);

s2 = s1; // converting ctor

present_span(s1);
present_span(s2);
}
结果(控制台)
s.size(): 5
elems: 1 2 3 4 5

s.size(): 4
elems: 10 11 12 13

s.size(): 5
elems: 1 2 3 4 5

s.size(): 5
elems: 1 2 3 4 5

默认复制构造函数

constexpr span( const span& other ) noexcept = default;

默认复制构造函数复制大小和数据指针。结果 span 具有

  • size() == other.size()
  • data() == other.data()

复杂度

常数 - O(1)

示例

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

template <typename Type, std::size_t Extent>
void present_span(std::span<Type, Extent> s) {
std::cout << "s.size(): " << s.size() << '\n';
std::cout << "elems: ";
for(int num : s) {
std::cout << num << ' ';
}
std::cout << "\n\n";
}

int main() {
std::vector<int> source = { 1, 2, 3, 4, 5 };
std::vector<int> source2 = { 5, 4, 3, 2, 1 };

std::span<int> s1 = source;
std::span<int> s2 = source2;
present_span(s1);
present_span(s2);

s2 = s1; // copy ctor

present_span(s1);
present_span(s2);
}
结果(控制台)
s.size(): 5
elems: 1 2 3 4 5

s.size(): 5
elems: 5 4 3 2 1

s.size(): 5
elems: 1 2 3 4 5

s.size(): 5
elems: 1 2 3 4 5
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。