命名空间
变体
操作

std::ranges::size

来自 cppreference.cn
< cpp‎ | ranges
 
 
范围库
范围适配器
 
定义于头文件 <ranges>
定义于头文件 <iterator>
inline namespace /* 未指定 */ {

    inline constexpr auto size = /* 未指定 */;

}
(自 C++20 起)
(定制点对象)
调用签名
template< class T >

    requires /* 见下文 */

constexpr auto size( T&& t );
(自 C++20 起)

在常数时间内计算 t 中元素的数量。

给定 子表达式,其中 t 表示(可能 具体化 的)结果对象为 E,并且 E 的类型为 T

上述可诊断的非良构情况会导致当 ranges::size(E) 出现在模板实例化的直接上下文中时发生替换失败

内容

定制点对象

名称 ranges::size 表示一个定制点对象,它是一个常量 函数对象,其类型为 字面量 semiregular 类类型。为了阐述目的,其类型的 cv 非限定版本表示为 __size_fn

__size_fn 的所有实例均相等。在相同参数上调用 __size_fn 类型的不同实例的效果是等效的,无论表示实例的表达式是左值还是右值,以及是否是 const 限定的(但是,不要求可调用 volatile 限定的实例)。因此,ranges::size 可以自由复制,并且其副本可以互换使用。

给定类型集合 Args...,如果 std::declval<Args>()... 满足上述 ranges::size 的参数要求,则 __size_fn 建模

否则,__size_fn 的任何函数调用运算符都不参与重载解析。

[编辑] 注解

每当 ranges::size(e) 对表达式 e 有效时,返回类型都是类整数

C++20 标准要求,如果底层 size 函数调用返回 prvalue,则返回值是从具体化的临时对象移动构造的。所有实现都直接返回 prvalue。后 C++20 提案 P0849R8 对此要求进行了修正,以与实现相匹配。

表达式 ranges::distance(e) 也可用于确定范围 e 的大小。与 ranges::size(e) 不同,即使 e 是无大小范围,ranges::distance(e) 也能工作,但代价是在这种情况下具有线性复杂度。

[编辑] 示例

#include <iostream>
#include <ranges>
#include <type_traits>
#include <vector>
 
int main()
{
    auto v = std::vector<int>{};
    std::cout << "ranges::size(v) == " << std::ranges::size(v) << '\n';
 
    auto il = {7};     // std::initializer_list
    std::cout << "ranges::size(il) == " << std::ranges::size(il) << '\n';
 
    int array[]{4, 5}; // array has a known bound
    std::cout << "ranges::size(array) == " << std::ranges::size(array) << '\n';
 
    static_assert(std::is_signed_v<decltype(std::ranges::size(v))> == false);
}

输出

ranges::size(v) == 0
ranges::size(il) == 1
ranges::size(array) == 2

[编辑] 缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布行为 正确行为
P2602R2 C++20 存在禁止通过 ADL 找到的某些非成员 size 的机制 移除了此类机制

[编辑] 参见

返回一个有符号整数,等于范围的大小
(定制点对象)[编辑]
指定范围在常数时间内知道其大小
(概念) [编辑]
返回迭代器和哨兵之间,或范围的开始和结束之间的距离
(算法函数对象)[编辑]
(C++17)(C++20)
返回容器或数组的大小
(函数模板) [编辑]