给定结构的两个对象s1和s2,它们只包含布尔类型成员,当s1的这个成员为真时,检查s2的每个成员是否为真

时间:2018-01-14 23:07:56

标签: c++

我有一个结构S,它只包含一个布尔类型Bool的元素。这些元素不存储在数组中。因此,结构的形式为struct s { Bool a, b, c, ... };

现在,我有两个o1o2类型S的对象,我需要有一个函数test,它执行以下操作:

bool test(S o1, S o2)
{
    if (o1.a && !o2.a)
        return false;
    if (o1.b && !o2.b)
        return false;
    if (o1.c && !o2.c)
        return false;

    ...

    return true;
}

有没有更好的方法呢?结果S可能在将来发生变化(即可能会添加某些字段;其他字段可能会被删除),而test应执行相同的工作。

例如,我们可以reinterpret_cast &o1&o2指向Bool*类型的指针并执行检查,但也许有更好的选择。

(请注意,S由我使用的库提供,因此我无法更改其定义。)

3 个答案:

答案 0 :(得分:2)

  

有没有更好的方法呢?

不。只需编写代码。

  

结构S可能在将来发生变化(即可能会添加某些字段;其他字段可能会被删除),而测试应执行相同的工作。

然后你必须检查每个接触其中一个字段的函数的实现的正确性,包括你的测试方法。

  

我们可以,例如,reinterpret_cast& o1和& o2指向Bool *类型的指针

因此,代码变得脆弱,依赖于不可移植的未定义行为并且主要是偶然地工作?这似乎是一种成本,而这一点并不是因为某人在未来某个时间可能改变某种方法

的微小好处。

只要像敏感的程序员一样编写合理的代码,不要乱用任何不给你买的疯狂技巧。

答案 1 :(得分:0)

由于我的其他答案没有很好,你也可以使用boost fusion:

#include <boost/fusion/adapted.hpp>
#include <boost/fusion/sequence.hpp>
#include <iostream>

struct S
{
  bool a;
  bool b;
  bool c;
};

BOOST_FUSION_ADAPT_STRUCT(S,
  (bool, a)
  (bool, b)
  (bool, c)
)

using namespace boost::fusion;

int main()
{
  S foo = {true, false, false};
  S bar = {true, false, false};
  std::vector<bool> fooVec, barVec;
  for_each(foo, [&fooVec](bool b){ fooVec.push_back(b); });
  for_each(bar, [&barVec](bool b){ barVec.push_back(b); });

  bool result = true;

  for (int i = 0; i <fooVec.size(); ++i)
  {
    result = result && (fooVec[i] == barVec[i]);
  }

  std::cout << result << '\n';
}

唯一的问题是你必须确保宏镜像结构。

答案 2 :(得分:-2)

您可以使用指针迭代成员,我使用了常规bool但原则是相同的。

#include <iostream>

struct S { bool a; bool b; bool c; };

int main()
{
    S foo = {true, true, false};
    S bar = {true, false, false};

    bool* fooPtr = &foo.a;
    bool* barPtr = &bar.a;

    bool result = true;

    for (int i = 0; i < sizeof(foo) / sizeof(bool); ++i)
    {
        result = result && (*(fooPtr + i) == *(barPtr + i));
    }
    std::cout<<result<<'\n';
}

仅当结构的所有成员都是bool,或者所有bool连续存储在结构中时,这才有效。我不知道是否保证结构的成员之间没有填充类型相同...但我想知道在这种情况下插入填充的编译器。