【问题标题】:Can I multiply an int with a boolean in C++?我可以将 int 与 C++ 中的布尔值相乘吗?
【发布时间】:2016-01-13 12:49:07
【问题描述】:

我的 GUI 中有一个显示图表的小部件。如果我有多个图表,GUI 上的矩形中会显示一个图例。

我有一个QStringlist (legendText),其中包含图例的文本。如果不需要图例,legendText 将为空。如果有图例,legendText 将保留文本。

为了找到图例周围矩形的高度,我想执行以下操作:

 int height = 10;
 QStringList legendText;
 ...
 height = height * (legendText->size() > 0);
 ...

intboolean 相乘是一个好主意/好样式吗?我会遇到这样的问题吗?

【问题讨论】:

  • 在我看来,这个问题是关于风格和易读性的,而所谓​​的重复则涉及优化。
  • 可以,但牺牲了可读性。我更愿意明确表达我的意图。
  • 我不清楚你为什么要首先分配height,如果你可能正要取消它。这令人困惑,也妨碍了const-正确性。为什么不只是 int const height = 10 * (legendText->size() > 0);int const height = legendText->isEmpty() ? 0 : 10;(或任何其他可能的变体)?

标签: c++ int boolean


【解决方案1】:

按照标准(§4.5/6)完全没问题:

bool 类型的纯右值可以转换为int 类型的纯右值,使用 false 变为 0,true 变为 1。

但是,我建议使用isEmpty 而不是将size 与零height = height * (!legendText->isEmpty()); 进行比较

或者按照其他答案的建议使用条件运算符(但仍然使用isEmpty 而不是.size() > 0

【讨论】:

  • 我喜欢乘以!legendText->isEmpty()的无分支方法。
  • @RandallCook 您具体针对哪台机器进行优化?条件移动指令现在相当普遍,这使得这两个选项都没有分支。
【解决方案2】:

您可以使用条件(三元)运算符:

height = ( legendText->size() >0 ) ? height : 0 ;

【讨论】:

    【解决方案3】:

    这在技术上没问题,如果有点不清楚的话。

    bool 将被提升int,因此结果定义明确。但是,查看该代码我并没有立即获得您想要实现的语义。

    我会简单地写一些类似的东西:

    height = legendText->isEmpty() ? 0 : height;
    

    这让你的意图更加清晰。

    【讨论】:

    • 我会将其进一步缩减为 if (legendText->empty()) height = 0;。这是通常的写法。
    【解决方案4】:

    也许是这个?

    if(legendText->isEmpty())
    {
       height = 0;
    }
    

    int height = legendText->isEmpty() ? 0 : 10;
    

    【讨论】:

    • const 添加到此,您就很成功了。
    【解决方案5】:

    有些人可能会发现以下信息很有用(在每个时钟周期都很重要的高性能程序中应该考虑以下代码,这里的目的是展示替代技术,我不会在这种特殊情况下使用它)。

    如果您需要没有分支的快速代码,您可以使用按位运算符实现 int 乘法与布尔值。

    bool b = true;
    int  number = 10;
    number = b*number;
    

    可以优化为:

    number = (-b & number);
    

    如果btrue,那么-b-1 并且所有位都设置为1。否则所有位都是0
    布尔 NOT (!b) 可以通过对 b1 (b^1) 进行异或来实现。
    因此,在您的情况下,我们得到以下表达式:

    height = (-(legendText->isEmpty()^1) & height);
    

    【讨论】:

    • 如果你需要快速的代码,你可以告诉你的编译器优化你的代码。这就是编译器所做的。您的代码在非 2 的补码系统上会失败。
    • 编译器只执行简单的优化。他们不会为你做这项工作。他们必须理解代码,而我们还没有。
    • “您的代码在非 2 的补码系统上会失败”。这样的系统非常罕见......
    • (可以说)最易读的版本if (legendText->isEmpty()) height = 0; 已经被多个流行的编译器编译为无分支机器代码,即使只启用了最少的优化。您的答案已经只对稀有系统有用。
    • 是的,这段代码不应该在这种特殊情况下使用。这个答案更多地是关于提出可能在高性能程序中有用的替代技术。
    猜你喜欢
    • 1970-01-01
    • 2022-11-26
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 2019-10-11
    • 1970-01-01
    • 2012-02-13
    • 2023-01-26
    相关资源
    最近更新 更多