<ranges> 函数

<ranges>C++20 标头包括以下非成员帮助程序函数。

非成员函数 描述
beginC++20 获取指向范围中第一个元素的迭代器。
cbeginC++20 获取指向范围中第一个元素的 const 迭代器。
cendC++20 获取 const 选定的范围末尾的 sentinel。
cdataC++20 获取指向连续范围中第一个元素的 const 指针。
crbeginC++20 获取指向范围开头的反向 const 迭代器。
crendC++20 获取 crbegin() 返回结果末尾的 sentinel。
dataC++20 获取指向连续范围中第一个元素的指针。
emptyC++20 测试范围是否为空。
endC++20 获取范围末尾的 sentinel。
rbeginC++20 获取指向范围开头的反向迭代器。
rendC++20 获取指向范围末尾的 sentinel 的反向迭代器。
sizeC++20 获取范围的大小作为无符号值。
ssizeC++20 获取范围的大小作为带符号值。

其中许多“函数”作为自定义点对象实现。 自定义点对象是一个函数对象,可以在用户定义的类型上重载,同时强制约束哪些类型可以传递给函数对象。 净效果是,编译器确定是否有一个有效的自定义函数来调用传入的类型,或者是否应使用默认实现,或者调用格式是否不正确。

其中许多函数在 std 命名空间中具有相应的函数。 但是,在使用范围时,请改用这些帮助程序函数。 这些函数使用 C++20 概念,从而提供更好的编译时间错误。 由于它们作为自定义点实现,因此避免了与自变量依赖查找 (ADL) 相关的问题 (ADL) 和 const 正确性。

begin

获取指向范围中第一个元素的迭代器。

template<class T>
constexpr std::input_or_output_iterator auto begin(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

指向范围中第一个元素的迭代器:

包含元素 10、20 和 30 的向量的图片。第一个元素包含 10,标记为“begin()”。最后一个元素包含 30,并标记为“last element”。最后一个元素后面的假想框表示 sentinel,并标记为“end()”。

如果范围是一个数组,则返回 rg + 0 的等效项。 如果 auto(rg.begin()) 生成一个迭代器,则返回 auto(rg.begin()) 的等效项。 如果该表达式格式不正确,则当该表达式生成迭代器时使用 auto(begin(rg))

注解

ranges::begin() 适用于所有范围,而 std::begin() 可能不适用。

示例: begin

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector<int> v = {10, 20, 30};
    auto vi = std::ranges::begin(v);
    std::cout << *vi << ' ' << *++vi; // outputs 10 20
}

cbegin

获取指向范围中第一个元素的 const 迭代器。 迭代器可以访问范围中的元素,但不能修改它们。

template<class T>
constexpr std::input_or_output_iterator auto cbegin(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

指向范围中第一个元素的 const 迭代器:

包含元素 10、20 和 30 的向量的图片。第一个元素包含 10,标记为“cbegin()”。最后一个元素包含 30,并标记为“last element”。最后一个元素后面的假想框表示 sentinel,并标记为“cend()”。

如果范围是一个数组,则返回 rg + 0 的等效项。 如果 auto(rg.cbegin()) 生成一个迭代器,则返回 auto(rg.cbegin()) 的等效项。 如果该表达式格式不正确,则当该表达式生成迭代器时使用 auto(cbegin(rg))

注解

ranges::cbegin() 适用于所有范围,而 std::cbegin() 可能不适用。

示例: cbegin

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector<int> v = {10, 20, 30};
    auto vi = std::ranges::cbegin(v);
    std::cout << *vi; // outputs 10
    // *vi = 100; // error because the iterator is const
}

cdata

获取指向连续范围中第一个元素的 const 指针。

template<class T>
constexpr std::add_pointer_t<ranges::range_reference_t<const T>> cdata(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

基于范围类型的 const 指针,指向连续范围中的第一个元素数据。 例如,如果范围是一个整数向量,则返回值的类型为 const int *

示例: cdata

#include <ranges>
#include <iostream>

int main()
{
    std::vector v{10, 20, 30};
    std::string src{ "a string" };
   
    auto c_charPtr = std::ranges::cdata(src); // ptr is a const char *
    auto c_intPtr = std::ranges::cdata(v); // ptr2 is a const int *
    std::cout << c_charPtr << ", " << *c_intPtr << '\n'; // outputs a string, 10

    // *c_intPtr = 100; // error - cannot assign to a const pointer
    // *charPtr = 'A'; // error - cannot assign to a const pointer
}

cend

获取 const 选定的范围末尾的 sentinel。 迭代器可以访问范围中的元素,但不能修改它们。

template<class T>
constexpr std::sentinel_for<decltype(ranges::cbegin(std::declval<T>()))> auto cend(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

紧随 const 限定范围中最后一个元素的 sentinel:

包含元素 10、20 和 30 的向量的图片。第一个元素包含 10,标记为“cbegin()”。最后一个元素包含 30,并标记为“last element”。最后一个元素后面的假想框表示 sentinel,并标记为“cend()”。

注解

ranges::cend() 适用于所有范围,而 std::cend() 可能不适用。

示例: cend

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector<int> v = {10, 20, 30};
    auto i = std::ranges::cend(v);
    --i; // get off the sentinel and onto the last element in the range
    std::cout << *i; // outputs 30
    // *i = 300 // error because the iterator is const
}

crbegin

获取指向反向范围中第一个元素的反向 const 迭代器。 反向迭代器按相反顺序返回范围的元素。 范围本身不会反转;对它的访问会反转。

template<class T>
constexpr std::input_or_output_iterator auto crbegin(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

指向范围中第一个元素的反向 const 迭代器。 此迭代器按相反顺序返回范围的元素,从范围的末尾开始:

包含元素 10、20 和 30 的向量的图片。在最左边的元素(最左边的元素包含数字 10)之前有一个假想框,表示 sentinel。它标记为“crend()”。向量中的第一个元素包含数字 10,并标记为“last element”。向量中最右边的元素包含 30 并标记为“crbegin()”。

如果范围是一个数组,则返回 reverse_iterator{rg + n} 的等效项,其中 n 是数组中的元素数量。 如果 auto(rg.crbegin()) 生成一个迭代器,则返回 auto(rg.crbegin()) 的等效项。 如果该表达式格式不正确,则当该表达式生成迭代器时使用 auto(crbegin(rg))

注解

ranges::crbegin() 适用于所有双向范围,而 std::crbegin() 可能不适用。

示例: crbegin

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector v{10, 20, 30};
    auto vi = std::ranges::crbegin(v);
    std::cout << *vi << ' ' << *++vi << ' ' << *++vi; // outputs 30 20 10
    // vi[1] = 100; // error because the iterator is const
}

crend

获取 crbegin() 返回结果末尾的 sentinel。 反向迭代器按相反顺序返回范围的元素。 范围本身不会反转;对它的访问会反转。

template<class T>
std::sentinel_for<decltype(ranges::crbegin(declval<T>()))> auto crend(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

cbegin() 返回结果末尾的 sentinel。 sentinel 紧随范围反向视图中的最后一个元素:

包含元素 10、20 和 30 的向量的图片。在最左边的元素(最左边的元素包含数字 10)之前有一个假想框,表示 sentinel。它标记为“crend()”。向量中的第一个元素包含数字 10,并标记为“last element”。向量中最右边的元素包含 30 并标记为“crbegin()”。

注解

ranges::crend() 适用于所有双向范围,而 std::crend() 可能不适用。

crend

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector v{10, 20, 30};
    auto vi = std::ranges::crend(v);
    --vi; // get off the sentinel and onto the last element in the reversed range
    std::cout << *vi; // outputs 10
    // vi[0] = 300; // error because the iterator is const    
    std::cout << *vi << ' ' << *--vi << ' ' << *--vi; // outputs 10, 20, 30
}

data

获取指向连续范围中第一个元素的指针。

template<class T>
constexpr std::add_pointer_t<ranges::range_reference_t<T>> data(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

基于范围类型的指针,指向连续范围中的第一个元素。 例如,如果范围是一个整数向量,则返回值的类型为 int *

示例

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector v{10, 20, 30};
    std::string src{ "a string" };
   
    auto charPtr = std::ranges::data(src); // charPtr is a char *
    auto intPtr = std::ranges::data(v); // intPtr is an int *
    std::cout << charPtr << ", " << *intPtr << '\n'; // outputs a string, 10
    *intPtr = 100;
    *charPtr = 'A';
    std::cout << charPtr << ", " << *intPtr; // outputs A string, 100
}

empty

测试范围是否为空。

template<class T>
constexpr bool empty(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

如果范围没有元素,则返回 true;否则返回 false

示例

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
        std::vector v{10,20,30};
    std::vector<int> v2;

    std::cout << std::boolalpha << std::ranges::empty(v); // outputs false
    std::cout << std::boolalpha << ", " << std::ranges::empty(v2); // outputs true
}

end

获取范围末尾的 sentinel。

template<class T>
std::sentinel_for<ranges::iterator_t<T>> auto end(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

紧随范围中最后一个元素的 sentinel:

包含元素 10、20 和 30 的矢量的图片。第一个元素包含 10,被标记为 begin()。最后一个元素包含 30,被标记为“last element”。最后一个元素之后的虚框指示 sentinel,被标记为 end()。

注解

ranges::end() 适用于所有范围,而 std::end() 可能不适用。

示例

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector<int> v = {10, 20, 30};
    auto i = std::ranges::end(v);
    --i; // get off the sentinel and onto the last element in the range
    std::cout << *i; // outputs 30
}

rbegin

获取指向反向范围中第一个元素的反向迭代器。 反向迭代器按相反顺序返回范围的元素。 范围本身不会反转;对它的访问会反转。

template<class T>
constexpr std::input_or_output_iterator auto rbegin(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

指向范围中第一个元素的反向 迭代器。 此迭代器按相反顺序返回范围的元素,从反向范围的末尾开始:

包含元素 10、20 和 30 的向量的图片。在最左边的元素(最左边的元素包含数字 10)之前有一个假想框,表示 sentinel。它标记为“rend()”。向量中的第一个元素包含数字 10,并标记为“last element”。向量中最右边的元素包含 30 并标记为“rbegin()”。

如果范围是一个数组,则返回 reverse_iterator{rg + n} 的等效项,其中 n 是数组中的元素数量。 如果 auto(rg.rbegin()) 生成一个迭代器,则返回 auto(rg.rbegin()) 的等效项。 如果该表达式格式不正确,则当该表达式生成迭代器时使用 auto(rbegin(rg))

注解

ranges::rbegin() 适用于所有双向范围,而 std::rbegin() 可能不适用。

示例

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector v{10, 20, 30};
    auto vi = std::ranges::rbegin(v);
    std::cout << *vi << ' ' << *++vi << ' ' << *++vi; // outputs 30 20 10
}

rend

获取指向范围反向视图末尾的 sentinel 的反向迭代器。 反向迭代器按相反顺序返回范围的元素。 范围本身不会反转;对它的访问会反转。

template<class T>
constexpr 
std::sentinel_for<decltype(ranges::rbegin(std::declval<T>()))> auto rend(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

指向范围末尾 sentinel 的反向迭代器。 sentinel 紧随范围反向视图中的最后一个元素:

包含元素 10、20 和 30 的向量的图片。在最左边的元素(最左边的元素包含数字 10)之前有一个假想框,表示 sentinel。它标记为“rend()”。向量中的第一个元素包含数字 10,并标记为“last element”。向量中最右边的元素包含 30 并标记为“rbegin()”。

注解

ranges::rend() 适用于所有双向范围,而 std::rend() 可能不适用。

示例

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector v{10, 20, 30};
    auto vi = std::ranges::rend(v);
    --vi; // get off the sentinel and onto the last element in the reversed range
    std::cout << *vi; // outputs 10
    std::cout << *vi << ' ' << *--vi << ' ' << *--vi; // outputs 10, 20, 30
}

size

获取范围中的元素数作为无符号值。

template<class T>
constexpr /*unsigned integer-like type */ size(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

范围中的元素数作为无符号整数值。

备注

此函数以恒定时间执行。

示例

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector v{10, 20, 30};
    auto s = std::ranges::size(v); // s is a size_t
    std::cout << s; // outputs 3
}

ssize

获取范围的大小作为带符号值。

template<class T>
constexpr /* signed-integer-like type */ ssize(T&& rg);

参数

T
范围的类型。

rg
范围。

返回值

范围中的元素数作为带符号整数值。

备注

此函数以恒定时间执行。

示例

// requires /std:c++20 or later
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector v{10, 20, 30};
    auto s = std::ranges::ssize(v);
    std::cout << s; // outputs 3
}

另请参阅

<ranges>
什么是自定义对象