std::ranges::count要求范围支持迭代器且元素可比较,依赖operator==或自定义谓词,不支持lambda条件匹配,适用于vector、string等容器的值统计,需C++20标准和<algorithm>头文件。

std::ranges::count 要求范围必须支持迭代器,且元素可比较
它不是万能的“计数黑盒”,底层依赖 operator== 或自定义谓词,所以被统计类型必须能和给定值比较。比如 std::vector<:string></:string> 可以直接用,但若容器里是自定义类且没重载 operator==,编译会失败,报错类似:invalid operands to binary expression ('MyType' and 'const T')。
常见使用场景包括:统计 vector 中某个整数出现次数、查找 string 中特定字符频次、检查 array 是否全为某默认值。
- 必须传入一个范围(
std::ranges::range概念满足者),不能传裸指针+长度 - 第二个参数是待匹配的值(
const T&),不是迭代器或函数对象 - 不支持传入 lambda 做条件匹配 —— 那得用
std::ranges::count_if
正确调用 std::ranges::count 的三种典型写法
注意命名空间和 C++20 标准要求:头文件是 <algorithm>,不是 <ranges>;且需开启 C++20(如 GCC/Clang 加 -std=c++20)。
示例一:基础数值统计
立即学习“C++免费学习笔记(深入)”;
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3, 2, 4, 2};
auto n = std::ranges::count(v, 2); // 返回 3
std::cout << n << '\n';
}
示例二:字符串中字符计数
std::string s = "hello world"; auto cnt = std::ranges::count(s, 'l'); // 返回 3
示例三:自定义类型(前提是重载了 operator==)
struct Point { int x, y; };
bool operator==(const Point& a, const Point& b) { return a.x == b.x && a.y == b.y; }
std::vector<Point> pts = {{1,2}, {3,4}, {1,2}};
auto c = std::ranges::count(pts, Point{1,2}); // 返回 2
std::ranges::count 和 std::count 的关键区别在哪
最直接的区别是参数形式:std::count 接收一对迭代器(first, last),而 std::ranges::count 接收一个范围(比如容器本身)加一个值。
这意味着:
- 用
std::ranges::count时,无法只统计子区间(比如 vector 的中间 5 个元素),除非先用std::ranges::subrange或视图切片(如v | std::views::drop(2) | std::views::take(5))构造新范围 -
std::ranges::count对std::initializer_list、C 风格数组(如int arr[5])、std::string_view等都天然支持,无需手动取begin/end - 性能上无本质差异,都是 O(n),但 ranges 版本少写两个参数,可读性略高
容易踩的坑:编译失败、返回 0、或者根本没生效
最常见的三个问题:
- 忘记开启 C++20:编译器报
'ranges' is not a namespace-name或找不到count—— 检查编译选项和标准库版本(libstdc++ ≥ 11 / libc++ ≥ 14) - 传入了右值临时对象:比如
std::ranges::count(std::vector{1,2,3}, 2)在某些标准库实现中可能因绑定临时对象到 const 引用而引发 lifetime 问题,建议先存为变量再传 - 类型不匹配导致隐式转换失败:比如对
std::vector<long>传int值,某些编译器可能拒绝推导,显式写成std::ranges::count(v, 2L)更稳妥
真正要注意的是:它只做值匹配,不支持模式、正则、部分比较。想统计“大于 5 的元素个数”?必须换 std::ranges::count_if 并传 lambda。


















