Namespaces
Variants

std::ranges::size

来自 zh.cppreference.net
 
 
范围库
范围适配器
 
定义于头文件 <ranges>
定义于头文件 <iterator>
inline namespace /* unspecified */ {
    inline constexpr auto size = /* unspecified */;
}
(C++20 起)
(定制点对象)
调用签名
template< class T >
    requires /* see below */
constexpr auto size( T&& t );
(C++20 起)

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

给定 子表达式,其中 t 表示(可能实质化的)结果对象为 E,E 的类型为 T:

  • 如果 T 是未知边界数组,则 ranges::size(E) 非良构。
  • 否则,如果 T 是数组类型,则 ranges::size(E) 与 表达式等价于 decay-copy (std::extent_v<T>)(C++23 前)auto(std::extent_v<T>)(C++23 起)。
  • 否则,如果满足以下所有条件,则 ranges::size(E) 与 decay-copy (t.size())(C++23 前)auto(t.size())(C++23 起) 表达式等价:
    • ranges::disable_sized_range<std::remove_cv_t<T>> false。
    • decay-copy (t.size())(C++23 前)auto(t.size())(C++23 起) 是合法表达式,其类型为整数类类型。
  • 否则,如果满足以下所有条件,则 ranges::size(E) 与 decay-copy (size(t))(C++23 前)auto(size(t))(C++23 起) 表达式等价:
    • T
    • ranges::disable_sized_range<std::remove_cv_t<T>> 是类或枚举类型。false。
    • decay-copy (size(t))(C++23 前)auto(size(t))(C++23 起) 是合法表达式,其类型为整数类类型,其中 size 的含义如同仅通过执行实参依赖查找确立。
  • 否则,如果满足以下所有条件,则 ranges::size(E) 与 to-unsigned-like (ranges::end(t) - ranges::begin(t)) 表达式等价:
  • 否则,ranges::size(E) 非良构。

上述可诊断的非良构情况在 出现于模板实例化的立即语境中时会导致替换失败ranges::size(E)。

定制点对象

名称 ranges::size 表示一个 定制点对象 ,它是一个字面量 semiregular 类类型的常量 函数对象 。详细信息请参阅 定制点对象 。

注释

当表达式 e 满足 ranges :: size ( e ) 有效时,其返回类型为 类整数类型 。

C++20 标准要求:若底层 size 函数调用返回纯右值,则返回值应当从实质化的临时对象进行移动构造。但所有现有实现均直接返回该纯右值。该要求已通过后 C++20 提案 P0849R8 修正以与现有实现保持一致。

表达式 ranges:: distance ( e ) 也可用于确定范围 e 的大小。与 ranges :: size ( e ) 不同, ranges:: distance ( e ) 即使当 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)
返回容器或数组的大小
(函数模板)