Redis-plus-plus API使用指南:通用操作与数据类型接口介绍

🍑个人主页:Jupiter.
🚀 所属专栏:Redis
欢迎大家点赞收藏评论😊

在这里插入图片描述

在这里插入图片描述

目录

    • `通用 API`
        • `连接 Redis`
        • `1. get/set`
        • `2. exists 方法`
        • `3. del 方法`
        • `4. keys 方法`
        • `5. expire 方法`
        • `6. ttl 方法`
        • `7. type 方法`
        • `8. flushall 方法`
    • `String 类型 API`
        • `1. get/set 方法`
        • `2. mset 函数`
        • `3. mget 方法`
        • `4. append 方法`
        • `5. strlen 方法`
    • `List 类型 API`
        • `1. lpush 方法`
        • `2. rpush 方法`
        • `3. lpop 方法`
        • `4. rpop 方法`
        • `5. blpop 方法`
        • `6. brpop 方法`
        • `7. lrange 方法`
        • `8. llen 方法`
    • `Hash 类型 API`
        • `1. hset 与 hget 方法`
        • `2. hmset 与 hmget 方法`
        • `3. hkeys 与 hvals 方法`
        • `4. hgetall 方法`
        • `5. hexists 方法`
        • `6. hdel 方法`
        • `7. hlen 方法`
    • `Set 类型 API`
        • `1. sadd 和 smembers 方法`
        • `2. srem 方法`
        • `3. sismember 方法`
        • `4. scard 方法`
        • `5. sinter 与 sinterstore 方法`
        • `6. sunion 与 sunionstore 方法`
        • `7. sdiff 与 sdiffstore 方法`
    • `ZSet 类型 API`
        • `1. zadd 和 zrange 方法`
        • `2. zscore 方法`
        • `3. zrank 方法`
        • `4. zcard 方法`
        • `5. zrem 方法`
        • `6. zrangebyscore 方法`
    • `chrono时间字面量说明`
    • `C++中迭代器类型`
        • `1. 输入迭代器(Input Iterator)`
        • `2. 输出迭代器(Output Iterator)`
        • `std::copy函数`
        • `3. 前向迭代器(Forward Iterator)`
        • `4. 双向迭代器(Bidirectional Iterator)`
        • `5. 随机访问迭代器(Random Access Iterator)`
        • `迭代器类型的兼容性`


通用 API

连接 Redis

函数原型

  sw::redis::Redis::Redis(const std::string& uri);

参数说明

  • uri:Redis 服务器连接地址,格式为 tcp://host:port,如 tcp://127.0.0.1:6379
  • 若 Redis 有密码,格式为 tcp://:password@host:port

注意事项

  • 连接失败会抛出异常,建议使用 try-catch 块捕获
  • 一个 Redis 对象可以执行多个命令,内部维护连接池
1. get/set
  • 头文件:需要包含<sw/redis++/Redis.h>
    在这里插入图片描述
    参数说明
  • key:要设置值的键,std::string类型。
  • value:键对应的值,std::string类型。
  • params:用于设置额外选项,比如设置过期时间等,是sw::redis::SetParams类型对象。可以通过它调用ex(int seconds)方法设置过期时间(单位秒),px(int milliseconds)方法设置过期时间(单位毫秒),nx()表示仅当键不存在时设置,xx()表示仅当键已存在时设置。
  • sw::redis::StringView类型:就是std::string类型的const形式,只读字符串。

在这里插入图片描述

参数说明

  • key为要获取值的键,std::string类型。返回值是sw::redis::OptionalString类型,如果键不存在,OptionalString对象处于未初始化状态。
  • OptionalString 是 redis-plus-plus 库定义的一个类模板(类似标准库的 std::optional),用于表示 “可能存在或不存在的字符串”。它内部包含两个核心部分:
    • 一个布尔标志(标记是否有值)。
    • 一个 std::string 成员(存储实际字符串,仅当有值时有效)。
      它的设计目的是安全处理 “键不存在” 的场景(比如 get 命令查询不存在的键时,返回的 OptionalString 就处于 “无值” 状态)。
  • OptionalString 类重载了 operator* 运算符,用于直接访问内部存储的字符串。
  • OptionalString 还提供了 value() 成员函数,功能与 * 类似,用于显式获取内部字符串。
  • OptionalString类型对象是不支持C++中<<运算符重载的。可以自己实现,但是更简洁的方式就是直接使用这个类型的value方法或*解引用取到类的string成员。
  • optional 可以隐式转成 bool 类型, 可以直接在 if 中判定. 如果是无效元素, 就是返回 false。

代码示例:

int main()
{sw::redis::Redis redis("tcp://127.0.0.1:6379");redis.set("key1","11111");redis.set("key2","22222");redis.set("key5","55555",chrono::seconds(10));redis.set("key6","66666",chrono::milliseconds(6));sw::redis::OptionalString value = redis.get("key1");if(value){cout<<value.value()<<endl;}else{cout<<"bad optional access"<<endl;}value = redis.get("key10");if(value){cout<<value.value()<<endl;}else{cout<<"bad optional access"<<endl;}
}

编译报错:链接错误。是因为makefile里没有指明使用到的redis-plus-plus库。
在这里插入图片描述

g++ -o $@ $^ -std=c++17 /usr/local/lib/libredis++.a  /lib/x86_64-linux-gnu/libhiredis.a -pthread

运行结果:

11111
bad optional access
2. exists 方法

功能:检查给定的键是否存在。

函数原型

std::size_t exists(const std::string& key);

参数说明

  • key:要检查的键,std::string 类型
  • 返回值:std::size_t 类型,键存在返回 1,不存在返回 0

注意事项

  • 可以传入多个键,返回存在的键的数量:std::size_t exists(const std::string& key, const std::string&... keys);

示例代码

int main() {sw::redis::Redis redis("tcp://127.0.0.1:6379");std::string key = "name";std::size_t exists_count = redis.exists(key);if (exists_count > 0) {std::cout << "键存在" << std::endl;} else {std::cout << "键不存在" << std::endl;}return 0;
}
3. del 方法

功能:删除一个或多个键。

函数原型

std::size_t del(const std::string& key, const std::string&... keys);

参数说明

  • key:要删除的第一个键
  • keys:可变参数,后续要删除的键
  • 返回值:std::size_t 类型,表示实际成功删除的键的数量

注意事项

  • 即使键不存在,也不会报错,只会返回 0
  • 支持批量删除多个键,效率高于单个删除

示例代码

int main() {sw::redis::Redis redis("tcp://127.0.0.1:6379");std::string key1 = "name";std::string key2 = "age";std::size_t deleted_count = redis.del(key1, key2);if (deleted_count > 0) {std::cout << "成功删除 " << deleted_count << " 个键" << std::endl;} else {std::cout << "没有删除任何键" << std::endl;}return 0;
}
4. keys 方法

功能:查找所有符合给定模式的键。

函数原型

template <typename OutputIt>
void keys(const std::string& pattern, OutputIt out);

参数说明

  • pattern:匹配模式,支持通配符 *(任意字符)、?(单个字符)、[](字符范围)
  • out:输出迭代器,用于存储匹配的键
  • 返回值:无,结果通过迭代器写入容器

注意事项

  • 在生产环境中,对大型数据库使用 keys 命令可能会阻塞服务器,建议使用 scan 替代
  • 模式匹配可能会影响性能,尽量使用精确的前缀匹配

示例代码

int main() {sw::redis::Redis redis("tcp://127.0.0.1:6379");std::string pattern = "key*";redis.set("key", "111");redis.set("key2", "222");redis.set("key3", "333");// 准备容器存储结果std::vector<std::string> result;// 使用后插迭代器接收结果auto it = std::back_inserter(result);redis.keys(pattern, it);return 0;
}
5. expire 方法

功能:设置键的过期时间,单位为秒。

函数原型

bool expire(const std::string& key, std::chrono::seconds seconds);

参数说明

  • key:要设置过期时间的键
  • seconds:过期时间,std::chrono::seconds 类型
  • 返回值:bool 类型,设置成功返回 true,否则返回 false

注意事项

  • 若键不存在,返回 false
  • 可以使用 pexpire 方法设置毫秒级过期时间
  • 多次调用 expire 会覆盖之前的过期时间

示例代码

int main() {sw::redis::Redis redis("tcp://127.0.0.1:6379");std::string key = "name";bool success = redis.expire(key, std::chrono::seconds(10));if (success) {std::cout << "设置过期时间成功" << std::endl;} else {std::cout << "设置过期时间失败" << std::endl;}return 0;
}
6. ttl 方法

功能:获取键剩余的过期时间,单位为秒。

函数原型

sw::redis::OptionalInt ttl(const std::string& key);

参数说明

  • key:要查询的键
  • 返回值:sw::redis::OptionalInt 类型
    • 键不存在:返回 nullopt
    • 键存在但无过期时间:返回 -1
    • 键存在且有过期时间:返回剩余秒数

注意事项

  • 使用 pttl 方法可以获取毫秒级剩余时间
  • 对于不存在的键,返回的 OptionalInt 处于无效状态

示例代码

int main() {sw::redis::Redis redis("tcp://127.0.0.1:6379");std::string key = "name";sw::redis::OptionalInt ttl_value = redis.ttl(key);if (ttl_value) {if (*ttl_value == -1) {std::cout << "键存在但没有设置过期时间" << std::endl;} else {std::cout << "键剩余过期时间: " << *ttl_value << " 秒" << std::endl;}} else {std::cout << "键不存在" << std::endl;}return 0;
}
7. type 方法

功能:获取键对应值的数据类型。

函数原型

sw::redis::DataType type(const std::string& key);

参数说明

  • key:要查询的键
  • 返回值:sw::redis::DataType 枚举类型,可能值包括:
    • DataType::STRING:字符串类型
    • DataType::LIST:列表类型
    • DataType::SET:集合类型
    • DataType::ZSET:有序集合类型
    • DataType::HASH:哈希类型
    • DataType::NONE:键不存在

注意事项

  • 对于不存在的键,返回 DataType::NONE
  • 此方法仅返回主数据类型,不区分特殊类型(如 bitmap、hyperloglog 等)

示例代码

int main() {sw::redis::Redis redis("tcp://127.0.0.1:6379");std::string key = "name";sw::redis::DataType data_type = redis.type(key);if (data_type == sw::redis::DataType::STRING) {std::cout << "键类型: 字符串" << std::endl;} else if (data_type == sw::redis::DataType::LIST) {std::cout << "键类型: 列表" << std::endl;} else if (data_type == sw::redis::DataType::SET) {std::cout << "键类型: 集合" << std::endl;} else if (data_type == sw::redis::DataType::ZSET) {std::cout << "键类型: 有序集合" << std::endl;} else if (data_type == sw::redis::DataType::HASH) {std::cout << "键类型: 哈希" << std::endl;} else {std::cout << "键类型: 未知或不存在" << std::endl;}return 0;
}
8. flushall 方法

功能:清空所有数据库中的所有键。

函数原型

void flushall();

注意事项

  • 此操作不可逆,生产环境中需谨慎使用
  • 可以使用 flushdb 方法只清空当前数据库

示例代码

int main() {sw::redis::Redis redis("tcp://127.0.0.1:6379");redis.flushall();  // 清空所有数据库std::cout << "所有数据库已清空" << std::endl;return 0;
}

String 类型 API

1. get/set 方法

功能set 用于设置字符串键值对,get 用于获取字符串键的值。

函数原型

// 设置键值对
void set(const std::string& key, const std::string& value);
void set(const std::string& key, const std::string& value, const sw::redis::SetParams& params);// 获取键值
sw::redis::OptionalString get(const std::string& key);

参数说明

  • key:要设置或获取的键
  • value:要设置的值
  • paramssw::redis::SetParams 类型,用于设置额外选项:
    • ex(seconds):设置过期时间(秒)
    • px(milliseconds):设置过期时间(毫秒)
    • nx():仅当键不存在时设置
    • xx():仅当键已存在时设置
  • 返回值(get):sw::redis::OptionalString 类型,键存在时包含值,否则为无效状态

注意事项

  • OptionalString 不支持直接输出,需使用 value() 方法或解引用获取字符串
  • set 方法会覆盖已存在的键的值
  • SetParams 的方法可以链式调用,如 SetParams().ex(10).nx()

示例代码

int main()
{sw::redis::Redis redis("tcp://127.0.0.1:6379");// 基本设置redis.set("key1", "11111");redis.set("key2", "22222");// 设置带过期时间的键redis.set("key5", "55555", std::chrono::seconds(10));redis.set("key6", "66666", std::chrono::milliseconds(6));// 获取值并判断有效性sw::redis::OptionalString value = redis.get("key1");if (value) {std::cout << value.value() << std::endl;} else {std::cout << "bad optional access" << std::endl;}// 获取不存在的键value = redis.get("key10");if (value) {std::cout << value.value() << std::endl;} else {std::cout << "bad optional access" << std::endl;}
}
2. mset 函数

功能:批量设置多个键值对。

函数原型

// 初始化列表形式
void mset(const std::initializer_list<std::pair<std::string, std::string>>& pairs);// 迭代器形式
template <typename InputIt>
void mset(InputIt first, InputIt last);

参数说明

  • pairs:初始化列表,包含多个 std::pair<std::string, std::string> 类型的键值对
  • firstlast:迭代器范围,指向包含键值对的容器
  • 返回值:无

注意事项

  • mset 是原子操作,要么全部设置成功,要么全部失败
  • 会覆盖已存在的键的值,新键则直接创建
  • 相比多次调用 setmset 减少了网络交互,效率更高

示例代码

void test4(sw::redis::Redis& redis) {std::cout << "mset" << std::endl;redis.flushall();  // 清空所有数据,确保测试环境干净// 第一种写法: 使用初始化列表描述多个键值对// redis.mset({ std::make_pair("key1", "111"), std::make_pair("key2", "222"), std::make_pair("key3", "333") });// 第二种写法: 将多个键值对组织到容器中,通过迭代器传递给msetstd::vector<std::pair<std::string, std::string>> keys = {{"key1", "111"},{"key2", "222"},{"key3", "333"}};// 传入容器的起始和结束迭代器,批量设置键值对redis.mset(keys.begin(), keys.end());// 分别获取键值对,验证设置结果auto value = redis.get("key1");if (value) {  // 判断值是否存在std::cout << "value: " << value.value() << std::endl;  // 输出key1的值}value = redis.get("key2");if (value) {std::cout << "value: " << value.value() << std::endl;  // 输出key2的值}value = redis.get("key3");if (value) {std::cout << "value: " << value.value() << std::endl;  // 输出key3的值}
}
3. mget 方法

功能:批量获取多个键的值。

函数原型

// 初始化列表形式
template <typename OutputIt>
void mget(const std::initializer_list<std::string>& keys, OutputIt out);// 迭代器形式
template <typename InputIt, typename OutputIt>
void mget(InputIt first, InputIt last, OutputIt out);

参数说明

  • keys:初始化列表,包含多个要查询的键
  • firstlast:迭代器范围,指向包含要查询键的容器
  • out:输出迭代器,用于存储查询结果
  • 返回值:无,结果通过迭代器写入容器,类型为 std::vector<sw::redis::OptionalString>

注意事项

  • 结果顺序与输入键的顺序一致
  • 对于不存在的键,对应的 OptionalString 为无效状态
  • mget 是原子操作,相比多次调用 get 效率更高

示例代码

// 辅助函数:打印容器中的元素
template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}// 辅助函数:打印OptionalString容器(需处理无效值)
template<typename T>
inline void printContainerOptional(const T& container) {for (const auto& elem : container) {if (elem) {  // 检查值是否有效std::cout << elem.value() << std::endl;} else {std::cout << "(键不存在)" << std::endl;  // 键不存在时的提示}}
}void test5(sw::redis::Redis& redis) {std::cout << "mget" << std::endl;redis.flushall();  // 清空数据,准备测试// 先通过mset设置测试数据std::vector<std::pair<std::string, std::string>> keys = {{"key1", "111"},{"key2", "222"},{"key3", "333"}};redis.mset(keys.begin(), keys.end());// 存储查询结果的容器,元素类型为OptionalString(可能无效)std::vector<sw::redis::OptionalString> result;// 构造后插迭代器,用于将查询结果插入容器尾部auto it = std::back_inserter(result);// 传入要查询的键列表(包含一个不存在的key4)和迭代器redis.mget({"key1", "key2", "key3", "key4"}, it);// 打印查询结果(key4对应位置为无效值)printContainerOptional(result);
}
4. append 方法

功能:向字符串值末尾追加内容。

函数原型

size_t append(const std::string& key, const std::string& value);

参数说明

  • key:要操作的键
  • value:要追加的内容
  • 返回值:size_t 类型,追加后字符串的总长度

注意事项

  • 若键不存在,append 会创建该键并设置值为要追加的内容
  • 此操作是原子的,适合多线程环境下使用

示例代码

void test_append(sw::redis::Redis& redis) {redis.set("str", "Hello");size_t len = redis.append("str", " World");std::cout << "新长度: " << len << std::endl;  // 输出: 11auto value = redis.get("str");if (value) {std::cout << "值: " << value.value() << std::endl;  // 输出: Hello World}
}
5. strlen 方法

功能:获取字符串值的长度。

函数原型

size_t strlen(const std::string& key);

参数说明

  • key:要查询的键
  • 返回值:size_t 类型,字符串的长度;若键不存在,返回 0

注意事项

  • 对于非字符串类型的键,会返回错误
  • 长度按字节计算,对于包含多字节字符的字符串需注意

示例代码

void test_strlen(sw::redis::Redis& redis) {redis.set("str", "Hello");size_t len = redis.strlen("str");std::cout << "长度: " << len << std::endl;  // 输出: 5len = redis.strlen("nonexistent");std::cout << "不存在的键长度: " << len << std::endl;  // 输出: 0
}

List 类型 API

1. lpush 方法

功能:向列表的左侧(头部)插入元素。

函数原型

// 单个元素
long long lpush(const std::string& key, const std::string& value);// 初始化列表
long long lpush(const std::string& key, const std::initializer_list<std::string>& values);// 迭代器范围
template <typename InputIt>
long long lpush(const std::string& key, InputIt first, InputIt last);

参数说明

  • key:列表的键
  • value:要插入的单个元素
  • values:初始化列表,包含多个要插入的元素
  • firstlast:迭代器范围,指向包含要插入元素的容器
  • 返回值:long long 类型,插入后列表的长度

注意事项

  • 元素按参数顺序插入到列表头部,因此最终顺序与插入顺序相反
  • 若键不存在,会创建一个新的空列表并执行插入操作
  • 若键对应的值不是列表类型,会返回错误

示例代码

// 辅助函数:打印容器中的元素
template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}void test1(sw::redis::Redis& redis) {std::cout << "lpush 和 lrange" << std::endl;redis.flushall();  // 清空数据,准备测试// 1. 插入单个元素到列表头部redis.lpush("key", "111");// 2. 插入一组元素(基于初始化列表)redis.lpush("key", {"222", "333", "444"});  // 元素按顺序插入头部// 3. 插入一组元素(基于迭代器)std::vector<std::string> values = {"555", "666", "777"};redis.lpush("key", values.begin(), values.end());  // 容器元素按顺序插入头部// lrange:获取列表中指定范围的元素(0表示第一个元素,-1表示最后一个元素)std::vector<std::string> results;auto it = std::back_inserter(results);  // 迭代器用于接收结果redis.lrange("key", 0, -1, it);// 打印列表内容(元素顺序与插入顺序相反,因每次插入到头部)printContainer(results);
}
2. rpush 方法

功能:向列表的右侧(尾部)插入元素。

函数原型

// 单个元素
long long rpush(const std::string& key, const std::string& value);// 初始化列表
long long rpush(const std::string& key, const std::initializer_list<std::string>& values);// 迭代器范围
template <typename InputIt>
long long rpush(const std::string& key, InputIt first, InputIt last);

参数说明

  • lpush 相同,只是插入位置为列表尾部
  • 返回值:long long 类型,插入后列表的长度

注意事项

  • 元素按参数顺序插入到列表尾部,因此最终顺序与插入顺序相同
  • 其他注意事项与 lpush 相同

示例代码

void test_rpush(sw::redis::Redis& redis) {redis.flushall();// 从右侧插入元素redis.rpush("list", "a");redis.rpush("list", {"b", "c"});std::vector<std::string> res;redis.lrange("list", 0, -1, std::back_inserter(res));// 输出: a, b, cfor (const auto& val : res) {std::cout << val << " ";}std::cout << std::endl;
}
3. lpop 方法

功能:移除并返回列表的左侧(头部)第一个元素。

函数原型

sw::redis::OptionalString lpop(const std::string& key);

参数说明

  • key:列表的键
  • 返回值:sw::redis::OptionalString 类型,包含弹出的元素;若列表为空或不存在,返回无效状态

注意事项

  • 弹出操作会修改列表,移除被弹出的元素
  • 对于空列表,返回无效的 OptionalString

示例代码

void test_lpop(sw::redis::Redis& redis) {redis.flushall();redis.rpush("list", {"a", "b", "c"});auto elem = redis.lpop("list");if (elem) {std::cout << "弹出元素: " << elem.value() << std::endl;  // 输出: a}std::vector<std::string> res;redis.lrange("list", 0, -1, std::back_inserter(res));// 输出: b, cfor (const auto& val : res) {std::cout << val << " ";}
}
4. rpop 方法

功能:移除并返回列表的右侧(尾部)最后一个元素。

函数原型

sw::redis::OptionalString rpop(const std::string& key);

参数说明

  • lpop 相同,只是操作的是列表尾部元素
  • 返回值:sw::redis::OptionalString 类型,包含弹出的元素

注意事项

  • lpop 类似,只是操作的是列表尾部

示例代码

void test_rpop(sw::redis::Redis& redis) {redis.flushall();redis.rpush("list", {"a", "b", "c"});auto elem = redis.rpop("list");if (elem) {std::cout << "弹出元素: " << elem.value() << std::endl;  // 输出: c}std::vector<std::string> res;redis.lrange("list", 0, -1, std::back_inserter(res));// 输出: a, bfor (const auto& val : res) {std::cout << val << " ";}
}
5. blpop 方法

功能:阻塞式弹出列表左侧第一个元素,可同时监听多个列表。

函数原型

// 初始化列表形式
template <typename Rep, typename Period>
sw::redis::Optional<std::pair<std::string, std::string>> 
blpop(const std::initializer_list<std::string>& keys, const std::chrono::duration<Rep, Period>& timeout);// 迭代器形式
template <typename InputIt, typename Rep, typename Period>
sw::redis::Optional<std::pair<std::string, std::string>> 
blpop(InputIt first, InputIt last, const std::chrono::duration<Rep, Period>& timeout);

参数说明

  • keys:初始化列表,包含要监听的多个列表键
  • firstlast:迭代器范围,指向包含要监听列表键的容器
  • timeout:超时时间,若超过此时长仍无元素,返回无效状态
  • 返回值:sw::redis::Optional<std::pair<std::string, std::string>> 类型
    • 若成功弹出元素:pair 的第一个元素是来源列表名,第二个元素是弹出的元素
    • 若超时:返回无效状态

注意事项

  • 监听多个列表时,按参数顺序检查,有元素则立即弹出第一个非空列表的元素
  • 使用 std::chrono_literals 命名空间可简化超时时间写法,如 10s 表示10秒
  • 阻塞期间会暂停当前线程的执行,直到有元素或超时

示例代码

void test4(sw::redis::Redis& redis) {using namespace std::chrono_literals;  // 引入时间字面量,如10s// 监听多个列表,超时时间10秒auto result = redis.blpop({"key", "key2", "key3"}, 10s);if (result) {  // 超时前有元素弹出std::cout << "key:" << result->first << std::endl;  // 输出元素来源的列表名std::cout << "elem:" << result->second << std::endl;  // 输出弹出的元素} else {std::cout << "result 无效!" << std::endl;  // 超时无元素}
}
6. brpop 方法

功能:阻塞式弹出列表右侧最后一个元素,可同时监听多个列表。

函数原型

// 与 blpop 类似,只是弹出的是列表右侧元素
template <typename Rep, typename Period>
sw::redis::Optional<std::pair<std::string, std::string>> 
brpop(const std::initializer_list<std::string>& keys, const std::chrono::duration<Rep, Period>& timeout);

参数说明

  • blpop 相同,只是弹出的是列表右侧元素
  • 返回值:与 blpop 相同

注意事项

  • blpop 类似,只是操作的是列表右侧元素

示例代码

void test_brpop(sw::redis::Redis& redis) {using namespace std::chrono_literals;// 启动一个线程往列表添加元素std::thread t([&redis]() {std::this_thread::sleep_for(2s);redis.rpush("list1", "value1");});// 阻塞等待右侧元素auto result = redis.brpop({"list1", "list2"}, 5s);if (result) {std::cout << "从 " << result->first << " 弹出 " << result->second << std::endl;} else {std::cout << "超时" << std::endl;}t.join();
}
7. lrange 方法

功能:获取列表中指定范围的元素。

函数原型

template <typename OutputIt>
void lrange(const std::string& key, long long start, long long end, OutputIt out);

参数说明

  • key:列表的键
  • start:起始索引(0表示第一个元素,负数表示从尾部开始计数,如-1表示最后一个元素)
  • end:结束索引(包含在内)
  • out:输出迭代器,用于存储获取的元素
  • 返回值:无,结果通过迭代器写入容器

注意事项

  • start 大于列表长度,返回空列表
  • end 大于列表长度,会返回从 start 到列表末尾的所有元素
  • 索引从0开始,支持负数索引

示例代码

void test_lrange(sw::redis::Redis& redis) {redis.flushall();redis.rpush("list", {"a", "b", "c", "d", "e"});std::vector<std::string> res;// 获取所有元素redis.lrange("list", 0, -1, std::back_inserter(res));// 输出: a b c d eres.clear();// 获取索引1到3的元素redis.lrange("list", 1, 3, std::back_inserter(res));// 输出: b c d
}
8. llen 方法

功能:获取列表的长度。

函数原型

long long llen(const std::string& key);

参数说明

  • key:列表的键
  • 返回值:long long 类型,列表的长度;若键不存在,返回0;若键对应的值不是列表,返回错误

示例代码

void test_llen(sw::redis::Redis& redis) {redis.flushall();redis.rpush("list", {"a", "b", "c"});std::cout << "列表长度: " << redis.llen("list") << std::endl;  // 输出: 3std::cout << "不存在的列表长度: " << redis.llen("nonexistent") << std::endl;  // 输出: 0
}

Hash 类型 API

1. hset 与 hget 方法

功能hset 用于向哈希表设置字段-值对,hget 用于获取哈希表中指定字段的值。

函数原型

// hset 单个字段
long long hset(const std::string& key, const std::string& field, const std::string& value);// hset 单个pair字段
long long hset(const std::string& key, const std::pair<std::string, std::string>& field_value);// hset 初始化列表
long long hset(const std::string& key, const std::initializer_list<std::pair<std::string, std::string>>& fields_values);// hset 迭代器范围
template <typename InputIt>
long long hset(const std::string& key, InputIt first, InputIt last);// hget 获取字段值
sw::redis::OptionalString hget(const std::string& key, const std::string& field);

参数说明

  • key:哈希表的键
  • field:字段名
  • value:字段值
  • fields_values:包含多个字段-值对的初始化列表
  • firstlast:迭代器范围,指向包含字段-值对的容器
  • 返回值(hset):long long 类型,成功设置的新字段数量
  • 返回值(hget):sw::redis::OptionalString 类型,包含字段的值;若字段不存在,返回无效状态

注意事项

  • hset 可以设置单个或多个字段,对于已存在的字段会覆盖其值
  • hget 只能获取单个字段的值,若需要获取多个字段值,使用 hmget
  • 若哈希表不存在,hset 会创建一个新的哈希表

示例代码

void test1(sw::redis::Redis& redis) {// 1. 设置单个字段(字段f1,值111)redis.hset("key", "f1", "111");// 2. 通过pair设置单个字段(字段f2,值222)redis.hset("key", std::make_pair("f2", "222"));// 3. 通过初始化列表设置多个字段redis.hset("key", {std::make_pair("f3", "333"),std::make_pair("f4", "444")});// 4. 通过容器迭代器设置多个字段std::vector<std::pair<std::string, std::string>> fields = {std::make_pair("f5", "555"),std::make_pair("f6", "666")};redis.hset("key", fields.begin(), fields.end());// 获取字段f3的值auto result = redis.hget("key", "f3");if (result) {  // 字段存在std::cout << "result: " << result.value() << std::endl;  // 输出: 333} else {std::cout << "result 无效!" << std::endl;  // 字段不存在}
}
2. hmset 与 hmget 方法

功能hmset 用于批量设置哈希表的字段-值对,hmget 用于批量获取多个字段的值。

函数原型

// hmset 初始化列表
void hmset(const std::string& key, const std::initializer_list<std::pair<std::string, std::string>>& fields_values);// hmset 迭代器范围
template <typename InputIt>
void hmset(const std::string& key, InputIt first, InputIt last);// hmget 初始化列表
template <typename OutputIt>
void hmget(const std::string& key, const std::initializer_list<std::string>& fields, OutputIt out);// hmget 迭代器范围
template <typename InputIt, typename OutputIt>
void hmget(const std::string& key, InputIt first, InputIt last, OutputIt out);

参数说明

  • hsethget 类似,支持批量操作
  • hmget 的返回结果通过输出迭代器写入容器,类型为 std::vector<sw::redis::OptionalString>

注意事项

  • hmsethset 批量版本的别名,功能相同
  • hmget 的结果顺序与输入字段的顺序一致
  • 对于不存在的字段,hmget 返回无效的 OptionalString

示例代码

void test5(sw::redis::Redis& redis) {// 1. 通过初始化列表批量设置字段-值对redis.hmset("key", {std::make_pair("f1", "111"),std::make_pair("f2", "222"),std::make_pair("f3", "333")});// 2. 通过容器迭代器批量设置字段-值对std::vector<std::pair<std::string, std::string>> pairs = {std::make_pair("f4", "444"),std::make_pair("f5", "555"),std::make_pair("f6", "666")};redis.hmset("key", pairs.begin(), pairs.end());// 批量获取字段f1、f2、f3的值std::vector<std::string> values;auto it = std::back_inserter(values);  // 迭代器接收结果redis.hmget("key", {"f1", "f2", "f3"}, it);printContainer(values);  // 输出: 111, 222, 333
}
3. hkeys 与 hvals 方法

功能hkeys 获取哈希表中所有字段名,hvals 获取哈希表中所有字段的值。

函数原型

// hkeys 获取所有字段名
template <typename OutputIt>
void hkeys(const std::string& key, OutputIt out);// hvals 获取所有字段值
template <typename OutputIt>
void hvals(const std::string& key, OutputIt out);

参数说明

  • key:哈希表的键
  • out:输出迭代器,用于存储结果
  • 返回值:无,结果通过迭代器写入容器

注意事项

  • 字段名和值的返回顺序不固定,与插入顺序无关
  • 对于空哈希表或不存在的键,返回空容器

示例代码

// 辅助函数:打印容器内容
template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}void test4(sw::redis::Redis& redis) {// 先设置测试数据redis.hset("key", "f1", "111");redis.hset("key", "f2", "222");redis.hset("key", "f3", "333");// 获取所有字段名std::vector<std::string> fields;auto itFields = std::back_inserter(fields);  // 迭代器接收字段名redis.hkeys("key", itFields);printContainer(fields);  // 输出: f1, f2, f3(顺序可能不同)// 获取所有字段的值std::vector<std::string> values;auto itValues = std::back_inserter(values);  // 迭代器接收值redis.hvals("key", itValues);printContainer(values);  // 输出: 111, 222, 333(顺序可能不同)
}
4. hgetall 方法

功能:获取哈希表中所有字段-值对。

函数原型

template <typename OutputIt>
void hgetall(const std::string& key, OutputIt out);

参数说明

  • key:哈希表的键
  • out:输出迭代器,用于存储结果,元素类型为 std::pair<std::string, std::string>
  • 返回值:无,结果通过迭代器写入容器

注意事项

  • 返回的字段-值对顺序不固定
  • 对于大型哈希表,此操作可能影响性能

示例代码

void test_hgetall(sw::redis::Redis& redis) {redis.flushall();redis.hset("user", "name", "Alice");redis.hset("user", "age", "30");redis.hset("user", "email", "alice@example.com");std::vector<std::pair<std::string, std::string>> fields_values;redis.hgetall("user", std::back_inserter(fields_values));for (const auto& p : fields_values) {std::cout << p.first << ": " << p.second << std::endl;}
}
5. hexists 方法

功能:检查哈希表中是否存在指定字段。

函数原型

bool hexists(const std::string& key, const std::string& field);

参数说明

  • key:哈希表的键
  • field:要检查的字段
  • 返回值:bool 类型,存在返回 true,否则返回 false

注意事项

  • 若哈希表不存在,返回 false

示例代码

void test_hexists(sw::redis::Redis& redis) {redis.flushall();redis.hset("user", "name", "Alice");bool exists = redis.hexists("user", "name");std::cout << "name 字段存在: " << std::boolalpha << exists << std::endl;  // 输出: trueexists = redis.hexists("user", "age");std::cout << "age 字段存在: " << std::boolalpha << exists << std::endl;  // 输出: false
}
6. hdel 方法

功能:删除哈希表中的一个或多个字段。

函数原型

long long hdel(const std::string& key, const std::string& field, const std::string&... fields);

参数说明

  • key:哈希表的键
  • fieldfields:要删除的字段
  • 返回值:long long 类型,成功删除的字段数量

注意事项

  • 对于不存在的字段,不会计入删除数量
  • 若哈希表不存在,返回 0

示例代码

void test_hdel(sw::redis::Redis& redis) {redis.flushall();redis.hset("user", {{"name", "Alice"},{"age", "30"},{"email", "alice@example.com"}});long long deleted = redis.hdel("user", "age", "email");std::cout << "删除的字段数量: " << deleted << std::endl;  // 输出: 2std::vector<std::string> fields;redis.hkeys("user", std::back_inserter(fields));// 输出: namefor (const auto& f : fields) {std::cout << f << " ";}
}
7. hlen 方法

功能:获取哈希表中字段的数量。

函数原型

long long hlen(const std::string& key);

参数说明

  • key:哈希表的键
  • 返回值:long long 类型,字段数量;若哈希表不存在,返回 0

示例代码

void test_hlen(sw::redis::Redis& redis) {redis.flushall();redis.hset("user", {{"name", "Alice"},{"age", "30"}});std::cout << "字段数量: " << redis.hlen("user") << std::endl;  // 输出: 2std::cout << "不存在的哈希表字段数量: " << redis.hlen("nonexistent") << std::endl;  // 输出: 0
}

Set 类型 API

1. sadd 和 smembers 方法

功能sadd 向集合添加元素,smembers 获取集合中的所有元素。

函数原型

// sadd 单个元素
long long sadd(const std::string& key, const std::string& member);// sadd 初始化列表
long long sadd(const std::string& key, const std::initializer_list<std::string>& members);// sadd 迭代器范围
template <typename InputIt>
long long sadd(const std::string& key, InputIt first, InputIt last);// smembers 获取所有元素
template <typename OutputIt>
void smembers(const std::string& key, OutputIt out);

参数说明

  • key:集合的键
  • member:要添加的单个元素
  • members:要添加的多个元素(初始化列表)
  • firstlast:迭代器范围,指向要添加的元素
  • out:输出迭代器,用于存储集合中的元素
  • 返回值(sadd):long long 类型,成功添加的新元素数量(不包括已存在的元素)
  • 返回值(smembers):无,结果通过迭代器写入容器

注意事项

  • 集合中的元素是唯一的,添加已存在的元素不会改变集合
  • smembers 返回的元素顺序是无序的
  • 对于大型集合,smembers 可能影响性能,建议使用 sscan 替代

示例代码

void test1(sw::redis::Redis& redis) {// 1. 添加单个元素redis.sadd("key", "111");// 2. 通过初始化列表添加多个元素redis.sadd("key", {"222", "333", "444"});// 3. 通过容器迭代器添加多个元素std::set<std::string> elems = {"555", "666", "777"};redis.sadd("key", elems.begin(), elems.end());// 获取集合所有元素(用vector存储,也可用set保持去重特性)std::vector<std::string> result;// 构造插入迭代器,指定插入位置为容器尾部(效果同back_inserter)auto it = std::inserter(result, result.end());redis.smembers("key", it);printContainer(result);  // 输出: 111, 222, 333, 444, 555, 666, 777(顺序不确定)
}
2. srem 方法

功能:从集合中移除一个或多个元素。

函数原型

// 单个元素
long long srem(const std::string& key, const std::string& member);// 初始化列表
long long srem(const std::string& key, const std::initializer_list<std::string>& members);// 迭代器范围
template <typename InputIt>
long long srem(const std::string& key, InputIt first, InputIt last);

参数说明

  • key:集合的键
  • membermembers:要移除的元素
  • 返回值:long long 类型,成功移除的元素数量(不包括不存在的元素)

注意事项

  • 移除不存在的元素不会报错,只会返回 0
  • 若集合不存在,返回 0

示例代码

void test_srem(sw::redis::Redis& redis) {redis.flushall();redis.sadd("set", {"a", "b", "c", "d"});long long removed = redis.srem("set", "b", "d");std::cout << "移除的元素数量: " << removed << std::endl;  // 输出: 2std::vector<std::string> members;redis.smembers("set", std::back_inserter(members));// 输出: a c(顺序不确定)for (const auto& m : members) {std::cout << m << " ";}
}
3. sismember 方法

功能:检查元素是否是集合的成员。

函数原型

bool sismember(const std::string& key, const std::string& member);

参数说明

  • key:集合的键
  • member:要检查的元素
  • 返回值:bool 类型,是成员返回 true,否则返回 false

注意事项

  • 若集合不存在,返回 false

示例代码

void test_sismember(sw::redis::Redis& redis) {redis.flushall();redis.sadd("set", {"a", "b", "c"});bool is_member = redis.sismember("set", "b");std::cout << "b 是成员: " << std::boolalpha << is_member << std::endl;  // 输出: trueis_member = redis.sismember("set", "d");std::cout << "d 是成员: " << std::boolalpha << is_member << std::endl;  // 输出: false
}
4. scard 方法

功能:获取集合中元素的数量。

函数原型

long long scard(const std::string& key);

参数说明

  • key:集合的键
  • 返回值:long long 类型,元素数量;若集合不存在,返回 0

示例代码

void test_scard(sw::redis::Redis& redis) {redis.flushall();redis.sadd("set", {"a", "b", "c"});std::cout << "集合元素数量: " << redis.scard("set") << std::endl;  // 输出: 3std::cout << "不存在的集合元素数量: " << redis.scard("nonexistent") << std::endl;  // 输出: 0
}
5. sinter 与 sinterstore 方法

功能sinter 计算多个集合的交集,sinterstore 计算多个集合的交集并存储到新集合。

函数原型

// sinter 初始化列表
template <typename OutputIt>
void sinter(const std::initializer_list<std::string>& keys, OutputIt out);// sinter 迭代器范围
template <typename InputIt, typename OutputIt>
void sinter(InputIt first, InputIt last, OutputIt out);// sinterstore 初始化列表
long long sinterstore(const std::string& dest, const std::initializer_list<std::string>& keys);// sinterstore 迭代器范围
template <typename InputIt>
long long sinterstore(const std::string& dest, InputIt first, InputIt last);

参数说明

  • keys:要计算交集的多个集合的键
  • firstlast:迭代器范围,指向要计算交集的集合键
  • out:输出迭代器,用于存储交集结果
  • dest:存储交集结果的新集合的键
  • 返回值(sinterstore):long long 类型,交集中的元素数量

注意事项

  • 若输入的集合中有一个为空,交集也为空
  • 若某个集合不存在,视为空集
  • sinterstore 会覆盖 dest 集合(如果已存在)

示例代码

void test5(sw::redis::Redis& redis) {// 初始化两个集合redis.sadd("key1", {"111", "222", "333"});redis.sadd("key2", {"111", "222", "444"});// 计算交集(111, 222)std::set<std::string> result;auto it = std::inserter(result, result.end());  // 接收交集结果redis.sinter({"key1", "key2"}, it);printContainer(result);  // 输出: 111, 222
}void test6(sw::redis::Redis& redis) {// 初始化两个集合redis.sadd("key1", {"111", "222", "333"});redis.sadd("key2", {"111", "222", "444"});// 计算交集并存储到key3,返回元素个数long long len = redis.sinterstore("key3", {"key1", "key2"});std::cout << "len: " << len << std::endl;  // 输出: 2// 验证存储结果std::set<std::string> result;auto it = std::inserter(result, result.end());redis.smembers("key3", it);printContainer(result);  // 输出: 111, 222
}
6. sunion 与 sunionstore 方法

功能sunion 计算多个集合的并集,sunionstore 计算多个集合的并集并存储到新集合。

函数原型

// sunion 初始化列表
template <typename OutputIt>
void sunion(const std::initializer_list<std::string>& keys, OutputIt out);// sunion 迭代器范围
template <typename InputIt, typename OutputIt>
void sunion(InputIt first, InputIt last, OutputIt out);// sunionstore 初始化列表
long long sunionstore(const std::string& dest, const std::initializer_list<std::string>& keys);// sunionstore 迭代器范围
template <typename InputIt>
long long sunionstore(const std::string& dest, InputIt first, InputIt last);

参数说明

  • sintersinterstore 类似,只是计算的是并集
  • 返回值(sunionstore):long long 类型,并集中的元素数量

注意事项

  • 并集包含所有集合中的所有元素,重复元素只保留一个
  • sunionstore 会覆盖 dest 集合(如果已存在)

示例代码

void test_sunion(sw::redis::Redis& redis) {redis.flushall();redis.sadd("set1", {"a", "b", "c"});redis.sadd("set2", {"c", "d", "e"});std::vector<std::string> result;redis.sunion({"set1", "set2"}, std::back_inserter(result));// 输出: a b c d e(顺序不确定)for (const auto& val : result) {std::cout << val << " ";}std::cout << std::endl;
}void test_sunionstore(sw::redis::Redis& redis) {redis.flushall();redis.sadd("set1", {"a", "b", "c"});redis.sadd("set2", {"c", "d", "e"});long long len = redis.sunionstore("set3", {"set1", "set2"});std::cout << "并集元素数量: " << len << std::endl;  // 输出: 5std::vector<std::string> result;redis.smembers("set3", std::back_inserter(result));// 输出: a b c d e(顺序不确定)for (const auto& val : result) {std::cout << val << " ";}
}
7. sdiff 与 sdiffstore 方法

功能sdiff 计算多个集合的差集,sdiffstore 计算多个集合的差集并存储到新集合。

函数原型

// sdiff 初始化列表
template <typename OutputIt>
void sdiff(const std::initializer_list<std::string>& keys, OutputIt out);// sdiff 迭代器范围
template <typename InputIt, typename OutputIt>
void sdiff(InputIt first, InputIt last, OutputIt out);// sdiffstore 初始化列表
long long sdiffstore(const std::string& dest, const std::initializer_list<std::string>& keys);// sdiffstore 迭代器范围
template <typename InputIt>
long long sdiffstore(const std::string& dest, InputIt first, InputIt last);

参数说明

  • sinter 类似,计算的是差集(存在于第一个集合但不存在于其他集合的元素)
  • 返回值(sdiffstore):long long 类型,差集中的元素数量

示例代码

void test_sdiff(sw::redis::Redis& redis) {redis.flushall();redis.sadd("set1", {"a", "b", "c", "d"});redis.sadd("set2", {"c", "d", "e", "f"});std::vector<std::string> result;redis.sdiff({"set1", "set2"}, std::back_inserter(result));// 输出: a b(顺序不确定)for (const auto& val : result) {std::cout << val << " ";}
}

ZSet 类型 API

1. zadd 和 zrange 方法

功能zadd 向有序集合添加元素(包含分数),zrange 按索引范围获取有序集合的元素。

函数原型

// zadd 单个元素
long long zadd(const std::string& key, double score, const std::string& member);// zadd 单个pair元素
long long zadd(const std::string& key, const std::pair<double, std::string>& score_member);// zadd 初始化列表
long long zadd(const std::string& key, const std::initializer_list<std::pair<double, std::string>>& score_members);// zadd 迭代器范围
template <typename InputIt>
long long zadd(const std::string& key, InputIt first, InputIt last);// zrange 获取元素(仅成员)
template <typename OutputIt>
void zrange(const std::string& key, long long start, long long stop, OutputIt out);// zrange 获取元素(成员+分数)
template <typename OutputIt>
void zrange(const std::string& key, long long start, long long stop, OutputIt out);

参数说明

  • key:有序集合的键
  • score:元素的分数(用于排序)
  • member:元素的值
  • score_member:包含分数和成员的 pair
  • startstop:索引范围(0表示第一个元素,-1表示最后一个元素)
  • out:输出迭代器,用于存储结果
    • 若容器元素类型为 std::string,仅存储成员
    • 若容器元素类型为 std::pair<std::string, double>,存储成员和对应的分数
  • 返回值(zadd):long long 类型,成功添加的新元素数量

注意事项

  • 有序集合中的元素是唯一的,但分数可以相同
  • 若元素已存在,zadd 会更新其分数
  • zrange 按分数升序返回元素,使用 zrevrange 可按分数降序返回

示例代码

void test1(sw::redis::Redis& redis) {// 1. 添加单个元素(成员"吕布",分数99)redis.zadd("key", "吕布", 99);// 2. 通过初始化列表添加多个元素redis.zadd("key", {std::make_pair("赵云", 98),std::make_pair("典韦", 97)});// 3. 通过容器迭代器添加多个元素std::vector<std::pair<std::string, double>> members = {std::make_pair("关羽", 95),std::make_pair("张飞", 93)};redis.zadd("key", members.begin(), members.end());// zrange用法1:仅获取成员(容器为vector<string>)std::vector<std::string> memberResults;auto it = std::back_inserter(memberResults);redis.zrange("key", 0, -1, it);  // 0到-1表示所有元素(按分数升序)printContainer(memberResults);  // 输出: 张飞(93), 关羽(95), 典韦(97), 赵云(98), 吕布(99)// zrange用法2:获取成员+分数(容器为vector<pair<string, double>>)std::vector<std::pair<std::string, double>> membersWithScore;auto it2 = std::back_inserter(membersWithScore);redis.zrange("key", 0, -1, it2);// 遍历输出(每个元素是pair<成员, 分数>)for (const auto& p : membersWithScore) {std::cout << p.first << ":" << p.second << std::endl;}
}
2. zscore 方法

功能:获取有序集合中指定成员的分数。

函数原型

sw::redis::Optional<double> zscore(const std::string& key, const std::string& member);

参数说明

  • key:有序集合的键
  • member:要查询的成员
  • 返回值:sw::redis::Optional<double> 类型,包含成员的分数;若成员不存在,返回无效状态

注意事项

  • 分数是 double 类型,可以是整数或小数
  • 若有序集合不存在,返回无效状态

示例代码

void test4(sw::redis::Redis& redis) {std::cout << "zscore" << std::endl;redis.flushall();// 初始化有序集合redis.zadd("key", "zhangsan", 90);redis.zadd("key", "lisi", 91);redis.zadd("key", "wangwu", 92);redis.zadd("key", "zhaoliu", 93);// 获取"zhangsan"的分数auto score = redis.zscore("key", "zhangsan");if (score) {  // 成员存在std::cout << "score: " << score.value() << std::endl;  // 输出: 90} else {std::cout << "score 无效" << std::endl;  // 成员不存在}
}
3. zrank 方法

功能:获取有序集合中指定成员的排名(按分数升序)。

函数原型

sw::redis::Optional<long long> zrank(const std::string& key, const std::string& member);

参数说明

  • key:有序集合的键
  • member:要查询的成员
  • 返回值:sw::redis::Optional<long long> 类型,包含成员的排名(从0开始);若成员不存在,返回无效状态

注意事项

  • 排名按分数升序计算,分数最低的成员排名为0
  • 使用 zrevrank 可获取按分数降序的排名

示例代码

void test5(sw::redis::Redis& redis) {// 初始化有序集合redis.zadd("key", "zhangsan", 90);redis.zadd("key", "lisi", 91);redis.zadd("key", "wangwu", 92);redis.zadd("key", "zhaoliu", 93);// 获取"zhaoliu"的排名(分数最高,排名3)auto rank = redis.zrank("key", "zhaoliu");if (rank) {  // 成员存在std::cout << "rank: " << rank.value() << std::endl;  // 输出: 3} else {std::cout << "rank 无效" << std::endl;  // 成员不存在}
}
4. zcard 方法

功能:获取有序集合中元素的数量。

函数原型

long long zcard(const std::string& key);

参数说明

  • key:有序集合的键
  • 返回值:long long 类型,元素数量;若有序集合不存在,返回0

示例代码

void test_zcard(sw::redis::Redis& redis) {redis.flushall();redis.zadd("zset", {{"a", 10},{"b", 20},{"c", 30}});std::cout << "有序集合元素数量: " << redis.zcard("zset") << std::endl;  // 输出: 3
}
5. zrem 方法

功能:从有序集合中移除一个或多个元素。

函数原型

// 单个元素
long long zrem(const std::string& key, const std::string& member);// 初始化列表
long long zrem(const std::string& key, const std::initializer_list<std::string>& members);// 迭代器范围
template <typename InputIt>
long long zrem(const std::string& key, InputIt first, InputIt last);

参数说明

  • key:有序集合的键
  • membermembers:要移除的元素
  • 返回值:long long 类型,成功移除的元素数量

示例代码

void test_zrem(sw::redis::Redis& redis) {redis.flushall();redis.zadd("zset", {{"a", 10},{"b", 20},{"c", 30}});long long removed = redis.zrem("zset", "b");std::cout << "移除的元素数量: " << removed << std::endl;  // 输出: 1std::vector<std::string> members;redis.zrange("zset", 0, -1, std::back_inserter(members));// 输出: a cfor (const auto& m : members) {std::cout << m << " ";}
}
6. zrangebyscore 方法

功能:获取有序集合中分数在指定范围内的元素。

函数原型

// 仅获取成员
template <typename OutputIt>
void zrangebyscore(const std::string& key, double min, double max, OutputIt out);// 获取成员+分数
template <typename OutputIt>
void zrangebyscore(const std::string& key, double min, double max, OutputIt out);// 带参数的版本
template <typename OutputIt>
void zrangebyscore(const std::string& key, double min, double max, const sw::redis::ZRangeByScoreParams& params, OutputIt out);

参数说明

  • key:有序集合的键
  • minmax:分数范围
  • params:可选参数,可设置 limitoffset
  • out:输出迭代器,用于存储结果

注意事项

  • 分数范围默认包含边界值,使用 (minmax) 可表示不包含边界
  • 可通过 ZRangeByScoreParams 设置返回结果的偏移量和数量

示例代码

void test_zrangebyscore(sw::redis::Redis& redis) {redis.flushall();redis.zadd("zset", {{"a", 10},{"b", 20},{"c", 30},{"d", 40},{"e", 50}});// 获取分数在20到40之间的元素std::vector<std::pair<std::string, double>> result;redis.zrangebyscore("zset", 20, 40, std::back_inserter(result));// 输出: b:20 c:30 d:40for (const auto& p : result) {std::cout << p.first << ":" << p.second << " ";}
}

chrono时间字面量说明

std::chrono_literals
std::chrono_literals 是 C++14 引入的命名空间,提供时间单位字面量,简化时间间隔的表示:

  • s:秒(对应 std::chrono::seconds
  • ms:毫秒(对应 std::chrono::milliseconds
  • us:微秒(对应 std::chrono::microseconds
  • ns:纳秒(对应 std::chrono::nanoseconds
  • min:分钟(对应 std::chrono::minutes
  • h:小时(对应 std::chrono::hours

使用方法
通过 using namespace std::chrono_literals; 引入命名空间后,可直接在数值后添加后缀表示时间:

// 10s 表示10秒,作为blpop的超时时间参数
auto result = redis.blpop({"key", "key2", "key3"}, 10s);

注意事项

  • 需包含头文件 <chrono> 才能使用
  • 时间字面量仅在 C++14 及以上标准中可用
  • 在函数内部引入命名空间,避免全局命名空间污染

C++中迭代器类型

1. 输入迭代器(Input Iterator)

输入迭代器是最基本的迭代器类型,只能读取元素,且只能单向移动(自增)。它支持以下操作:

  • 解引用(*):获取指向的元素(只读)
  • 箭头操作符(->):访问元素的成员
  • 自增(++):向前移动
  • 相等/不等比较(==, !=

输入迭代器通常用于从序列中读取数据,例如标准输入。

std中构造输入迭代器的函数:

  • std::istream_iterator:从输入流创建输入迭代器
#include <iostream>
#include <iterator>
#include <vector>int main() {// 使用istream_iterator从标准输入读取整数std::cout << "请输入一些整数(以非整数结束):" << std::endl;std::istream_iterator<int> input_iter(std::cin);std::istream_iterator<int> end_of_stream; // 流结束迭代器std::vector<int> numbers;// 使用输入迭代器读取数据while (input_iter != end_of_stream) {numbers.push_back(*input_iter);++input_iter;}return 0;
}

2. 输出迭代器(Output Iterator)

输出迭代器与输入迭代器相反,它只能用于写入元素,同样只能单向移动。它支持以下操作:

  • 解引用(*):获取指向的位置(只写)
  • 自增(++):向前移动

输出迭代器通常用于向序列中写入数据,例如标准输出。

std中构造输出迭代器的函数:

  • std::ostream_iterator:创建输出到流的迭代器
  • std::back_inserter:创建插入到容器尾部的迭代器
  • std::front_inserter:创建插入到容器头部的迭代器
  • std::inserter:创建插入到容器指定位置的迭代器

1. std::ostream_iterator
功能:创建一个输出迭代器,将元素写入到指定的输出流(如std::cout、文件流等),常用于直接输出元素。

函数原型:

#include <iterator>template< class T, class CharT = char, class Traits = std::char_traits<CharT> >
class ostream_iterator : public std::output_iterator_tag {
public:// 构造函数:绑定输出流和分隔符ostream_iterator( std::basic_ostream<CharT, Traits>& os, const CharT* delim );ostream_iterator( std::basic_ostream<CharT, Traits>& os ); // 无分隔符版本};

参数说明:

  • os:要写入的输出流(如std::cout)。
  • delim:可选参数,元素之间的分隔符(如空格、逗号),类型为const CharT*(通常传入字符串字面量)。

示例:

std::ostream_iterator<int> out_it(std::cout, " "); // 输出到控制台,元素间用空格分隔
*out_it = 10; // 输出 "10 "
++out_it;
*out_it = 20; // 输出 "20 "(最终显示 "10 20 ")

2. std::back_inserter

  • 功能:创建一个输出迭代器,通过容器的push_back()成员函数向容器尾部插入元素,适用于支持push_back()的容器(如std::vectorstd::liststd::deque)。

函数原型:

#include <iterator>template< class Container >
std::back_insert_iterator<Container> back_inserter( Container& c );
  • 参数说明: c:目标容器的引用,需支持push_back(const T&)push_back(T&&)成员函数。

  • 返回值: std::back_insert_iterator<Container>类型的迭代器,解引用并赋值时会调用c.push_back(值)

示例:

std::vector<int> vec;
auto it = std::back_inserter(vec); // 创建尾部插入迭代器
*it = 1; // 等价于 vec.push_back(1)
++it;
*it = 2; // 等价于 vec.push_back(2) → vec 变为 [1, 2]

3. std::front_inserter

  • 功能:创建一个输出迭代器,通过容器的push_front()成员函数向容器头部插入元素,适用于支持push_front()的容器(如std::liststd::dequestd::vector不支持)。

函数原型:

#include <iterator>template< class Container >
std::front_insert_iterator<Container> front_inserter( Container& c );

参数说明: c:目标容器的引用,需支持push_front(const T&)push_front(T&&)成员函数。

返回值: std::front_insert_iterator<Container>类型的迭代器,解引用并赋值时会调用c.push_front(值)

示例:

std::list<int> lst;
auto it = std::front_inserter(lst); // 创建头部插入迭代器
*it = 1; // 等价于 lst.push_front(1) → lst: [1]
++it;
*it = 2; // 等价于 lst.push_front(2) → lst: [2, 1]

std::inserter

  • 功能:创建一个输出迭代器,通过容器的insert()成员函数向容器指定位置插入元素,插入后原位置元素后移,适用于大多数有序容器(如std::vectorstd::liststd::set)。

函数原型:

#include <iterator>template< class Container >
std::insert_iterator<Container> inserter( Container& c, typename Container::iterator pos );

参数说明:

  • c:目标容器的引用,需支持insert(iterator, const T&)成员函数(大多数标准容器均支持)。
  • pos:插入位置的迭代器,元素将插入到pos指向的元素之前

返回值: std::insert_iterator<Container>类型的迭代器,解引用并赋值时会调用c.insert(pos, 值),且插入后迭代器会自动更新位置(保证后续插入在新元素之后)。

示例:

std::vector<int> vec = {1, 3};
auto it = std::inserter(vec, vec.begin() + 1); // 在索引1的位置(元素3前)插入
*it = 2; // 等价于 vec.insert(vec.begin() + 1, 2) → vec 变为 [1, 2, 3]
++it;
*it = 4; // 插入到上一个插入位置之后 → vec 变为 [1, 2, 4, 3]

总结

  • 这四个函数均返回输出迭代器,核心区别在于元素的写入/插入方式:
函数插入方式适用容器要求典型场景
ostream_iterator写入输出流(如控制台)无(依赖流对象)直接输出元素
back_inserter尾部插入(push_back支持push_back(如vector向容器尾部添加元素
front_inserter头部插入(push_front支持push_front(如list向容器头部添加元素
inserter指定位置插入(insert支持insert(大多数标准容器)向容器中间插入元素

使用时需根据容器特性选择合适的迭代器,避免因容器不支持对应成员函数(如vectorfront_inserter)导致编译错误。

#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};// 使用ostream_iterator输出到标准输出std::cout << "输出到控制台:";std::copy(numbers.begin(), numbers.end(), std::ostream_iterator<int>(std::cout, " "));std::cout << std::endl;// 使用back_inserter向容器尾部插入元素std::vector<int> squared_numbers;for_each(numbers.begin(), numbers.end(),[&](int n) { squared_numbers.push_back(n * n); });std::cout << "平方后的数字:";std::copy(squared_numbers.begin(), squared_numbers.end(),std::ostream_iterator<int>(std::cout, " "));std::cout << std::endl;return 0;
}   
std::copy函数
  • std::copy 是 C++ 标准库 <algorithm> 头文件中的一个常用算法,用于将一个序列(源)中的元素复制到另一个序列(目标)中,是迭代器模式的典型应用。

std::copy 的核心功能
从「源区间」复制元素到「目标区间」,复制的元素数量由源区间的长度决定。

  • 源区间:由两个迭代器 [first, last) 指定(左闭右开,包含 first 指向的元素,不包含 last 指向的元素)。
  • 目标区间:由一个起始迭代器 d_first 指定,需确保目标区间有足够的空间容纳复制的元素(否则会导致未定义行为)。

语法

#include <algorithm>// 复制 [first, last) 中的元素到 [d_first, d_first + (last - first))
template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last, OutputIt d_first );
  • 返回值:指向目标区间中最后一个复制元素的下一个位置的迭代器。

简单示例

1. 复制数组元素到另一个数组

#include <iostream>
#include <algorithm> // 包含 std::copyint main() {int source[] = {1, 2, 3, 4, 5};int dest[5]; // 目标数组,需提前分配足够空间// 复制 source[0..4] 到 dest[0..4]std::copy(std::begin(source), std::end(source), std::begin(dest));// 打印结果for (int num : dest) {std::cout << num << " "; // 输出:1 2 3 4 5}return 0;
}

2. 复制容器元素到另一个容器

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator> // 包含 ostream_iteratorint main() {std::vector<int> source = {10, 20, 30};std::vector<int> dest;// 为目标容器预留空间(可选,但能提高效率)dest.reserve(source.size());// 复制 source 到 dest(使用 back_inserter 自动插入尾部)std::copy(source.begin(), source.end(), std::back_inserter(dest));// 直接复制到控制台(使用 ostream_iterator)std::cout << "复制到控制台:";std::copy(dest.begin(), dest.end(), std::ostream_iterator<int>(std::cout, " "));// 输出:复制到控制台:10 20 30 return 0;
}

关键注意事项

  1. 目标区间的空间
    若目标是普通数组或已初始化的容器,必须确保其大小 ≥ 源区间的元素数量,否则会溢出。
    若目标是动态容器(如 vector),可配合 std::back_inserter 自动扩容(无需提前分配空间)。

  2. 迭代器类型要求
    源区间的迭代器需满足「输入迭代器」要求(如 vector::begin()、数组指针),目标区间的迭代器需满足「输出迭代器」要求(如 vector::begin()ostream_iterator)。

  3. 与手动循环的对比
    std::copy 本质上等价于手动循环复制(如下),但代码更简洁,且由标准库优化,效率相同:

    // 等价于 std::copy(first, last, d_first)
    while (first != last) {*d_first = *first;++first;++d_first;
    }
    

常见应用场景

  • 容器间的元素复制(如 vector 复制到 list)。
  • 配合 ostream_iterator 直接输出容器内容到控制台或文件。
  • 配合 back_inserter 向容器动态添加元素(无需手动 push_back)。

std::copy 是 C++ 中处理元素复制的基础工具,掌握它能简化代码并提高可读性。

3. 前向迭代器(Forward Iterator)
  • 前向迭代器结合了输入迭代器和输出迭代器的功能,既可以读取也可以写入元素,并且可以在序列中向前移动。与输入/输出迭代器不同,前向迭代器可以多次遍历同一个序列。

  • 前向迭代器支持输入和输出迭代器的所有操作,还可以被复制和赋值。

std中构造前向迭代器的函数:

  • std::forward_list::begin() / std::forward_list::end():获取forward_list的前向迭代器
  • std::unordered_set::begin() / std::unordered_set::end():获取unordered_set的前向迭代器
  • std::unordered_map::begin() / std::unordered_map::end():获取unordered_map的前向迭代器
#include <iostream>
#include <forward_list>int main() {std::forward_list<int> numbers = {1, 2, 3, 4, 5};std::cout << "初始列表:";for (auto it = numbers.begin(); it != numbers.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;// 使用前向迭代器修改元素for (auto it = numbers.begin(); it != numbers.end(); ++it) {*it *= 2; // 将每个元素乘以2}std::cout << "修改后的列表:";for (auto it = numbers.begin(); it != numbers.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;return 0;
}
4. 双向迭代器(Bidirectional Iterator)
  • 双向迭代器在前向迭代器的基础上增加了向后移动的能力(自减操作)。它支持前向迭代器的所有操作,还增加了:

  • 自减(--):向后移动

  • 双向迭代器可以在序列中向前和向后移动,适用于需要双向遍历的场景。

std中构造双向迭代器的函数:

  • std::list::begin() / std::list::end():获取list的双向迭代器
  • std::list::rbegin() / std::list::rend():获取list的反向双向迭代器
  • std::set::begin() / std::set::end():获取set的双向迭代器
  • std::map::begin() / std::map::end():获取map的双向迭代器
#include <iostream>
#include <list>int main() {std::list<int> numbers = {1, 2, 3, 4, 5};std::cout << "正向遍历:";for (auto it = numbers.begin(); it != numbers.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;std::cout << "反向遍历:";for (auto it = numbers.end(); it != numbers.begin(); ) {--it;std::cout << *it << " ";}std::cout << std::endl;// 在列表中间插入元素auto it = numbers.begin();std::advance(it, 2); // 移动到第三个元素numbers.insert(it, 10); // 在3前面插入10std::cout << "插入后的列表:";for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
5. 随机访问迭代器(Random Access Iterator)
  • 随机访问迭代器是功能最强大的迭代器类型,它支持双向迭代器的所有操作,还可以进行随机访问(直接跳转到序列中的任意位置)。

随机访问迭代器增加的操作:

  • 加减整数(+, -, +=, -=):移动指定数量的元素
  • 下标操作([]):访问指定位置的元素
  • 比较操作(<, >, <=, >=):比较迭代器位置

std中构造随机访问迭代器的函数:

  • std::vector::begin() / std::vector::end():获取vector的随机访问迭代器
  • std::deque::begin() / std::deque::end():获取deque的随机访问迭代器
  • std::array::begin() / std::array::end():获取array的随机访问迭代器
  • std::pointer_iterator:将指针包装成随机访问迭代器
  • std::next() / std::prev():获取迭代器的下一个/上一个位置
迭代器类型的兼容性

需要注意的是,这些迭代器类型是有层次结构的:

  • 随机访问迭代器 也是 双向迭代器
  • 双向迭代器 也是 前向迭代器
  • 前向迭代器 也是 输入迭代器和输出迭代器

这意味着,接受输入迭代器的算法也可以使用任何更高级的迭代器,而接受随机访问迭代器的算法则不能使用低级别的迭代器。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/93615.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/93615.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于遗传编程的自动程序生成

这里写目录标题核心概念与工作原理1. 个体表示&#xff1a;树结构2. 初始化种群3. 适应度评估4. 选择5. 遗传操作&#xff08;繁殖&#xff09;6. 新一代种群形成7. 终止条件基于遗传编程的符号回归示例问题示例GP实现符号回归&#xff08;Deap&#xff09;GP实现符号回归&…

flowable汇总查询方式

背景&#xff1a;小程序开发申请流程。使用flowable流程框架。用户需要在后台统揽用户申请的汇总表。 设计思路&#xff1a;通过查询流程实例分页查询获取数据&#xff0c; 其中可以通过查询条件进行查询&#xff0c;查询条件是流程申请时添加到流程变量当中的&#xff0c;方便…

力扣438:找到字符串中所有的字母异位词

力扣438:找到字符串中所有的字母异位词题目思路代码题目 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 思路 我们先不看异位词这个条件&#xff0c;如何在字符串s中找到字符串p。我们可以…

ruoyi-vue(十一)——代码生成

大部分项目里其实有很多代码都是重复的&#xff0c;几乎每个基础模块的代码都有增删改查的功能&#xff0c;而这些功能都是大同小异&#xff0c; 如果这些功能都要自己去写&#xff0c;将会大大浪费我们的精力降低效率。所以这种重复性的代码可以使用代码生成。一 代码生成使用…

neo4j导入导出方法

在 Neo4j 中&#xff0c;如果需要将数据从 一个环境导出&#xff0c;再 导入到另一个环境&#xff08;如从开发环境迁移到生产环境&#xff09;&#xff0c;可以通过以下方法实现&#xff1a;方法 1&#xff1a;使用 neo4j-admin 导出和导入&#xff08;完整数据库迁移&#xf…

Diamond基础2:开发流程之LedDemo

文章目录1.关联VS Code2.Diamond工程目录3.Led Demo开发流程4.烧写bit文件5.传送门1.关联VS Code 和Vivado一样&#xff0c;Diamond也可以使用第三方的编辑器&#xff0c;VS Code编辑器因为可以安装各种插件&#xff0c;并且对verilog开发的支持也算完善&#xff0c;所以很受欢…

Golang 后台技术面试套题 1

文章目录1.网络1.1 浏览器从输入网址到展示页面&#xff0c;描述下整个过程&#xff1f;1.2 HTTP 502&#xff0c;503 和 504 是什么含义&#xff1f;区别以及如何排查&#xff1f;1.3 HTTPS 通信过程为什么要约定加密密钥 code&#xff0c;用非对称加密不行吗&#xff1f;1.4 …

【科研绘图系列】R语言绘制蝶形条形图蝶形柱状堆积图

文章目录 介绍 加载R包 数据下载 导入数据 数据预处理 画图 系统信息 参考 介绍 【科研绘图系列】R语言绘制蝶形条形图&蝶形柱状堆积图 加载R包 library(tidyverse) library(ggsignif) library(RColorBrewer) library(dplyr) library(reshape2) library(grid

Jeecg后端经验汇总

Jeecg是一个不错的低代码平台&#xff0c;极大的降低了很多开发人员接私活的难度&#xff0c;也极大的降低了开发全套功能的难度。但是一码归一码&#xff0c;开发人员的水平很一般&#xff0c;如下&#xff1a;&#xff08;1&#xff09;普通用户可以修改管理员密码&#xff0…

ethernet_input到应用层处理简单分析

1、驱动层&#xff1a;从硬件读取数据并构造pbuf中断触发后&#xff0c;驱动层的接收任务&#xff08;或轮询函数&#xff09;会从网卡硬件读取数据&#xff0c;并将其封装为 LWIP 可识别的pbuf结构体&#xff08;LWIP 的数据缓冲区&#xff09;。关键函数&#xff1a;驱动自定…

C#WPF实战出真汁05--左侧导航

1、左侧导航设计要点清晰的信息架构 确保导航结构层次分明&#xff0c;主分类与子分类逻辑清晰&#xff0c;避免过度嵌套。使用分组、缩进或分隔线区分不同层级&#xff0c;保持视觉可读性。直观的图标与标签 为每个导航项搭配简洁的图标&#xff0c;强化视觉识别。标签文字需简…

大模拟 Major

题目来源&#xff1a;2025 Wuhan University of Technology Programming Contest 比赛链接&#xff1a;Dashboard - 2025 Wuhan University of Technology Programming Contest - Codeforces 题目大意&#xff1a; 模拟 16 支队伍的瑞士轮比赛结果&#xff0c;规则太多&…

【手撕JAVA多线程】1.从设计初衷去看JAVA的线程操作

目录 前言 概述 主动阻塞/唤醒 代码示例 实现 为什么必须在同步块中使用 计时等待是如何实现的 被动阻塞/唤醒 为什么要有被动阻塞/唤醒 实现&#xff08;锁升级&#xff09; 前言 JAVA多线程相关的内容很多很杂&#xff0c;但工作中用到的频率不高&#xff0c;用到…

UE5多人MOBA+GAS 46、制作龙卷风技能

文章目录创建龙卷风GA创建蒙太奇创捷一系列GE添加数据表添加到角色中创建龙卷风GA GA_Tornado 添加标签 // 龙卷风冷却CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Tornado_Cooldown)// 通用技能伤害CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Generic_Dama…

如何在ubuntu下安装libgpiod库

以下是关于如何在ubuntu下安装libgpiod库的两种安装方式以及遇到ubuntu存在多个工具链导致编译失败的解决方法。如果想要自由选择使用不同版本的libgpiod&#xff0c;可以选择手动编译安装方式&#xff0c;系统安装默认1.6.3版本(ubuntu22.04)。手动编译安装1、在github上下载要…

qt vs2019编译QXlsx

1、安装ActivePerl2、打开pro文件&#xff0c;直接编译即可第一个简单实例&#xff1a;#include "xlsxcellrange.h" #include "xlsxchart.h" #include "xlsxchartsheet.h" #include "xlsxdocument.h" #include "xlsxrichstring.h…

计算机存储器分类和层次结构详解

存储器是计算机系统的核心部件之一&#xff0c;其核心功能是存储程序&#xff08;指令&#xff09;和数据&#xff0c;是冯诺依曼体系结构“存储程序”概念的物质基础。它直接关系到计算机系统的性能、容量和成本。 存储器核心内容总览表分类维度存储器层级技术实现速度容量成本…

通过rss订阅小红书,程序员将小红书同步到自己的github主页

title: 通过rss订阅小红书&#xff0c;程序员将小红书同步到自己的github主页 tags: 个人成长 categories:杂谈最近在做一些新的尝试&#xff0c;把文本的内容转化为漫画和图片&#xff0c;方便大众阅读&#xff0c;恰好小红书很适合分发这些内容&#xff0c;于是我开通了小红书…

麒麟KylinOS V10-SP3 安装FastGPT

1. 操作系统环境CPU&#xff1a;20核 Xeon(R) Platinum 8457C 内存&#xff1a;64GB GPU&#xff1a;4090 操作系统&#xff1a;KylinOS-V10-SP32. 安装docker、docker-compose、fastgpt下载安装docker、docker-compose1. 下载docker docker 下载地址&#xff1a; https://do…

前端/在vscode中创建Vue3项目

Contenthtml input元素添加css样式使用js添加交互按钮点击提示输入框字符计数使用 npm 来管理项目包安装 Node.js初始化项目安装依赖包创建一个基于 Vite 的 Vue 项目创建项目进入项目目录安装依赖调用代码格式化工具启动开发服务器在浏览器中访问html input元素 <input ty…