【问题标题】:Proper way to compare BitmaskType with zero?将 BitmaskType 与零进行比较的正确方法?
【发布时间】:2012-11-24 19:55:32
【问题描述】:

根据BitmaskType 概念,实现必须确保以下语句的格式正确:(列于§17.5.2.1.3.4)

如果表达式 X & Y 不为零,则在对象 X 中设置值 Y。

其中 X 和 Y 是概念类型 BitmaskType

在 gcc 4.7 中尝试以下简单代码 sn-p 时出现模板推导错误:

#include <future>

int main() {
    (std::launch::async & std::launch::async) != 0;
}

错误:

error: no match for 'operator!=' in '(std::launch)1 != 0'
... followed by tons of deduction errors

这是 gcc 中的一个错误,还是我只是在这里出错了?如果是,执行此类检查的正确方法是什么?

我已经检查了 gcc 错误列表,但找不到任何涵盖该主题的内容。

【问题讨论】:

    标签: c++ c++11 bitmask c++-concepts


    【解决方案1】:

    enum 类的成员并不意味着隐式转换为 int,反之亦然。您可以确保将位掩码类型转换为 int 或使用 enum 类的零值。我认为后者更可取:

    (std::launch::async & std::launch::async) != std::launch()
    

    (我还在按位 and 操作周围添加了括号,因为它比比较具有更高的优先级,并且按位 and 具有位掩码类型的布尔值并没有多大意义)。

    最简单的查看方法是 7.2 [enum.dcl] 第 9 段:

    ...请注意,没有为作用域枚举提供此隐式枚举到 int 的转换:...

    但是,这属于非规范性示例。跟踪标准中作用域规则的规则可能需要排除所有允许转换并且目前不太喜欢这个练习的情况。

    【讨论】:

    • 好的,谢谢,看起来不错。是的,我在复制一些代码时忘记添加大括号。 std::launch() 是否保证始终满足上述要求?
    • 我想是的。追它的方法是看枚举的默认初始化是什么意思。我很确定它会变成零初始化,但我现在还没有追上它。
    • 这是值初始化,而不是默认初始化,标量和枚举类型的值初始化总是零初始化。
    • 我认为这并不能真正解决问题。当然,在实践中使用枚举类来实现 BitmaskType 概念,但基本问题是 BitmaskType 具有枚举类似乎无法满足(也不能满足)的这个要求。我想这取决于如何解释“非零”。 cppreference 编辑器似乎也将其解释为文字 0 整数(afaik 枚举类无法满足)
    猜你喜欢
    • 1970-01-01
    • 2011-09-29
    • 2013-10-01
    • 2013-11-19
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多