如何实现存储不同长度std::bitset的列表并遍历调用模板函数处理?
处理不同大小
std::bitset实例的遍历方案 由于std::bitset<N>的大小N是模板参数,每个不同的N对应完全不同的类型,无法直接放入普通容器(比如std::vector)统一存储。下面提供两种实用的解决思路:
方法一:用std::variant统一管理(C++17及以上)
如果能提前枚举所有需要处理的N值,这种类型安全的方式最直接:
#include <bitset> #include <variant> #include <vector> #include <iostream> template<size_t N> bool do_sth_with_bitset(std::bitset<N> &target) { // 示例处理逻辑:翻转所有位并返回是否有位被设置 target.flip(); return target.any(); } int main() { // 定义包含所有目标bitset类型的variant using BitsetVariant = std::variant<std::bitset<8>, std::bitset<16>, std::bitset<32>>; std::vector<BitsetVariant> bitsets; bitsets.emplace_back(std::bitset<8>{0b1010}); bitsets.emplace_back(std::bitset<16>{0x1234}); bitsets.emplace_back(std::bitset<32>{0xdeadbeef}); // 遍历容器,用std::visit调用模板函数 for (auto& bs_var : bitsets) { std::visit([](auto& bs) { bool result = do_sth_with_bitset(bs); std::cout << "处理结果:" << std::boolalpha << result << "\n"; }, bs_var); } return 0; }
优缺点
- 优势:原生支持、类型安全,无额外运行时开销
- 局限:必须提前明确所有需要处理的
N值,无法应对未知范围的N
方法二:类型擦除(基类+继承)
如果N的范围不确定,可通过抽象基类封装不同类型的std::bitset:
#include <bitset> #include <vector> #include <memory> #include <iostream> template<size_t N> bool do_sth_with_bitset(std::bitset<N> &target) { target.flip(); return target.any(); } // 抽象基类,定义统一处理接口 class BitsetWrapper { public: virtual ~BitsetWrapper() = default; virtual bool process() = 0; }; // 模板派生类,包裹具体的std::bitset<N> template<size_t N> class ConcreteBitsetWrapper : public BitsetWrapper { private: std::bitset<N> bs; public: explicit ConcreteBitsetWrapper(std::bitset<N> b) : bs(std::move(b)) {} bool process() override { return do_sth_with_bitset(bs); } // 若需访问原始bitset,可添加getter std::bitset<N>& get_bitset() { return bs; } }; int main() { std::vector<std::unique_ptr<BitsetWrapper>> bitsets; bitsets.emplace_back(std::make_unique<ConcreteBitsetWrapper<8>>(std::bitset<8>{0b1010})); bitsets.emplace_back(std::make_unique<ConcreteBitsetWrapper<16>>(std::bitset<16>{0x1234})); bitsets.emplace_back(std::make_unique<ConcreteBitsetWrapper<32>>(std::bitset<32>{0xdeadbeef})); // 遍历调用统一接口 for (auto& wrapper : bitsets) { bool result = wrapper->process(); std::cout << "处理结果:" << std::boolalpha << result << "\n"; } return 0; }
优缺点
- 优势:灵活适配任意
N值,扩展性强 - 局限:需要额外编写包装类,存在虚函数调用的轻微运行时开销
注意事项
- 如果
do_sth_with_bitset不需要修改bitset,请将参数改为const std::bitset<N>&,对应的包装类成员也可设为const - 若需处理的
bitset类型极少,优先选择std::variant方案;类型较多或范围不确定时,类型擦除更合适
内容的提问来源于stack exchange,提问作者maytide
相关产品推荐
相关产品推荐

