将struct转换为bool值

时间:2018-04-17 14:15:23

标签: c++

我试图将带有布尔值的struct转换为boolean类型的另一个变量。我正在尝试使用static_castreinterpet_cast

int main()
{
    bool c,d;

    struct b {
        bool b1 = false; 
        bool b2 = false;
    };

    c = reinterpret_cast<uint8_t*>(&b);
    d = (static_cast<uint8_t*>(static_cast<void*>(&b)));
    cout <<c <<endl;
    cout <<d <<endl;

    return 0;
}

错误是:

main.cpp:22:38: error: expected primary-expression before ')' token
     c = reinterpret_cast<uint8_t*>(&b);
                                      ^
main.cpp:23:53: error: expected primary-expression before ')' token
     d = (static_cast<uint8_t*>(static_cast<void*>(&b)));

4 个答案:

答案 0 :(得分:4)

您无法将struct的实例转换为值为布尔值的bool或仅使用强制转换的所有成员转换为bool的实例。您需要告诉编译器如何使对象成为operator bool,并通过重载类的true来实现。在那里,您可以使用逻辑来判断是否应将其视为falsestruct Foo { bool a = true; bool b = true; bool c = false; operator bool() { return a || b || c; } }; int main() { Foo f; std::cout << static_cast<bool>(f); } 。那看起来像是

1

输出中:

post-receive

如果你有很多像你这样的成员说你应该考虑使用数组而不是单独的成员,这样你就可以编写一个循环。 C ++还没有反射,所以没有简单的方法可以告诉它或所有成员。

答案 1 :(得分:1)

如果您可以控制结构定义,那么这可能是使用逐位逻辑的好地方。如果你有多达128个布尔值,你可以在几个64位变量中处理它们。要检查单个布尔值,您可以使用掩码仅检查预期位。对于问题中描述的情况,您可以对64位变量进行布尔运算操作。像这样的东西:

id   |   title
---------------
1        parent
2        a_test
3        a_test2

因此,如果您已将struct b { uint64_t boolset_a; uint64_t boolset_b; } 定义为var_b类型,则可以执行此操作以查看其中是否存在任何类型struct b

我认为这应该是一种更有效的方法,因为它不需要100多个布尔运算来查看它们是否都是真的。

答案 2 :(得分:0)

我不会进行演员表但我会使用具有明确名称的成员函数:

int main()
{
  struct b {
    bool b1 = false;
    bool b2 = false;
    bool b3 = false;    
    bool AtLeastOneIsTrue() { return b1 || b2 || b3;  };
  };

  b str;
  str.b2 = true;
  cout << str.AtLeastOneIsTrue() << endl;

  str.b2 = false;
  cout << str.AtLeastOneIsTrue() << endl;
}

输出

1
0

但另一方面,如果你的结构有100个不同的bool成员,那么AtLeastOneIsTrue函数会很糟糕。然后,一系列bool或bool矢量更合适。

使用矢量的示例:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
  struct b {
    vector<bool> values;

    b(int numberofbools) { values.assign(numberofbools, false); };  // constructor

    bool AtLeastOneIsTrue()
    {
      for (bool v : values)
      {
        if (v)
          return true;
      }

      return false;
    };

    void Set(int number, bool value)
    {
      values[number] = value;
    }
  };


  b str(100);   // str has 100 bool values, all false

  cout << str.AtLeastOneIsTrue() << endl;  // print1 0

  str.Set(3, true);                        // set value number 3 to true
  cout << str.AtLeastOneIsTrue() << endl;  // prints 1
}

答案 3 :(得分:0)

恕我直言,你最好为结构创建一个成员函数或运算符,如NathanOliver所示,对那里的布尔值进行操作。事实上,你可以创建至少两个成员函数,一个告诉你任何布尔值是否为真,另一个告诉你所有是否为真。

我的方法,因为在未来的正常项目中可能需要在某种意义上扩展,是使用vector布尔值,或者更好的 map ,这样每个布尔值都可以给出一个名称,然后是两个函数(方法,如果它们属于一个更大的类,如配置实体),它们在这些标志上提供 all / any 计算。

下面显示了这种方法的快速而肮脏的示例(使用C ++ 11编译,对于auto循环进行编译,或者进行其他修改):

#include <iostream>
#include <string>
#include <map>

using namespace std;

typedef map<string, bool> Flags;

bool allOK(Flags & fl) {
    bool result = true;
    for (auto & kv : fl) { result &= kv.second; }
    return result;
}

bool anyOK(Flags & fl) {
    bool result = false;
    for (auto & kv : fl) { result |= kv.second; }
    return result;
}

int main(int argc, char * arg[])
{
    Flags flags;

    flags["a"] = true;
    flags["b"] = true;
    flags["the_third_flag"] = false;

    cout << "1. ALL OK: " << boolalpha << allOK(flags)
         << " - ANY OK: " << anyOK(flags) << '\n';

    flags["the_third_flag"] = true;
    cout << "2. ALL OK: " << boolalpha << allOK(flags)
         << " - ANY OK: " << anyOK(flags) << '\n';

    flags["a"] = false;
    flags["b"] = false;
    flags["the_third_flag"] = false;
    flags["a_last_flag"] = false;
    cout << "3. ALL OK: " << boolalpha << allOK(flags)
         << " - ANY OK: " << anyOK(flags) << '\n';

    return 0;
}