You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何向函数传递枚举类的多个位值并在函数内检查?

解决Enum Class传递多标志位的问题

这个问题我之前也碰到过!默认的C++ enum class是强类型枚举,它没有内置的位运算支持,而且你的枚举值定义也没给每个标志分配独立的二进制位——现在WriteRead默认是0和1,没法通过位掩码的方式组合判断。下面给你一步步解决的方案:

1. 重新定义枚举类,分配独立位并指定底层类型

首先修改枚举,给每个标志分配不同的二进制位,同时指定底层类型为整数类型(比如unsigned int),这样有足够的位来存储组合后的标志:

enum class BitFlags : unsigned int {
    None = 0,
    Write = 1 << 0,  // 对应二进制 0001
    Read = 1 << 1,   // 对应二进制 0010
    NumOfFlags = 1 << 2
};

这里加了None作为空标志,方便后续判断标志是否存在。

2. 重载位运算操作符

因为enum class不支持默认的|&等操作,我们需要手动重载这些运算符,让它支持标志组合:

#include <type_traits>  // 用于std::underlying_type_t

// 重载 | 运算符,用于组合多个标志
constexpr BitFlags operator|(BitFlags lhs, BitFlags rhs) {
    using UnderlyingType = std::underlying_type_t<BitFlags>;
    return static_cast<BitFlags>(static_cast<UnderlyingType>(lhs) | static_cast<UnderlyingType>(rhs));
}

// 重载 & 运算符,用于检查某个标志是否存在
constexpr BitFlags operator&(BitFlags lhs, BitFlags rhs) {
    using UnderlyingType = std::underlying_type_t<BitFlags>;
    return static_cast<BitFlags>(static_cast<UnderlyingType>(lhs) & static_cast<UnderlyingType>(rhs));
}

// 可选:重载 |= 运算符,方便原地修改标志
constexpr BitFlags& operator|=(BitFlags& lhs, BitFlags rhs) {
    lhs = lhs | rhs;
    return lhs;
}

std::underlying_type_t获取枚举的底层类型,避免硬编码类型,代码更通用。

3. 在函数内部检查标志

现在update函数就可以正常接收组合后的标志,并通过位与操作检查某个标志是否被设置:

void update(BitFlags flags) {
    // 检查Write标志是否被设置
    if ((flags & BitFlags::Write) != BitFlags::None) {
        // 这里写Write权限对应的逻辑
        // ...
    }

    // 检查Read标志是否被设置
    if ((flags & BitFlags::Read) != BitFlags::None) {
        // 这里写Read权限对应的逻辑
        // ...
    }

    // 也可以同时检查多个标志是否都被设置
    if ((flags & (BitFlags::Write | BitFlags::Read)) == (BitFlags::Write | BitFlags::Read)) {
        // 处理同时拥有Write和Read权限的逻辑
        // ...
    }
}

4. 正常调用函数

现在你就可以像最初想的那样调用update函数了:

int main() {
    update(BitFlags::Read | BitFlags::Write);  // 现在可以正常编译运行
    return 0;
}

如果你的项目用的是C20及以上版本,还可以用std::bitmask概念来简化实现,但上面的方法兼容所有支持enum class的C版本(C++11及以上)。

内容的提问来源于stack exchange,提问作者Oleg

火山引擎 最新活动