std::semiregular与std::regular模板的适用场景及使用示例咨询
std::semiregular 与 std::regular 适用场景及代码示例
注:二者核心差异为
std::regular在std::semiregular所有要求基础上,额外要求类型支持相等比较运算符==、!=。
std::semiregular 适用场景
当你编写的泛型组件只要求类型支持默认构造、复制、移动、赋值,不需要判断两个实例是否相等时,就可以用std::semiregular做类型约束,典型场景包括:
- 普通容器的元素类型(仅需要增删改、不需要去重/查找)
- 泛型对象池、缓存的存储类型
- 状态机的状态类型(仅需要赋值、状态转移,不需要相等判断)
示例代码:泛型对象池
#include <concepts> #include <vector> #include <stdexcept> // 约束元素类型满足semiregular,不需要相等比较能力 template<std::semiregular T> class ObjectPool { private: std::vector<T> pool; size_t used_cnt = 0; public: explicit ObjectPool(size_t init_size = 10) : pool(init_size) {} T& acquire() { if (used_cnt >= pool.size()) { pool.resize(pool.size() * 2); } return pool[used_cnt++]; } void release() { if (used_cnt == 0) throw std::out_of_range("no available object to release"); --used_cnt; } }; // 符合semiregular的业务类型,未实现相等比较 class ConnectionSession { private: int session_id; public: ConnectionSession() : session_id(0) {} ConnectionSession(int id) : session_id(id) {} // 编译器自动生成的复制、移动、析构函数满足要求 }; int main() { ObjectPool<ConnectionSession> session_pool(5); ConnectionSession& s1 = session_pool.acquire(); s1 = ConnectionSession(10086); session_pool.release(); return 0; }
std::regular 适用场景
当泛型逻辑需要判断两个实例是否等价时,就需要用std::regular做约束,典型场景包括:
- 关联容器的键类型、需要去重/查找的序列容器元素类型
- 依赖相等判断的泛型算法(去重、查找、匹配等)
- 可序列化类型(反序列化后需要和原对象做一致性校验)
- 单元测试中需要做断言对比的类型
示例代码:泛型去重工具
#include <concepts> #include <vector> #include <algorithm> // 依赖相等比较做去重,约束元素类型满足regular template<std::regular T> std::vector<T> deduplicate(std::vector<T> input) { std::sort(input.begin(), input.end()); auto duplicate_end = std::unique(input.begin(), input.end()); input.erase(duplicate_end, input.end()); return input; } // 符合regular的业务类型,实现了相等比较 class AccountUser { private: int uid; std::string username; public: AccountUser() : uid(0) {} AccountUser(int id, std::string name) : uid(id), username(std::move(name)) {} bool operator==(const AccountUser& other) const { return uid == other.uid && username == other.username; } bool operator<(const AccountUser& other) const { return uid < other.uid; } // 编译器自动生成的复制、移动、析构函数满足要求 }; int main() { std::vector<AccountUser> users = { AccountUser(1, "张三"), AccountUser(2, "李四"), AccountUser(1, "张三"), AccountUser(3, "王五") }; auto unique_users = deduplicate(users); return 0; }
内容的提问来源于stack exchange,提问作者ysbaekFox
相关产品推荐
相关产品推荐

