没有运算符的类等式检查==

时间:2017-05-25 13:04:38

标签: c++ c++11

我有一个非常大的数据模型,有许多成员,其中许多本身就是大数据模型,在这几个层次上都有这样的嵌套。顶级类表示序列化并发送到服务器进行备份的整体模型。作为调试步骤,我们希望反序列化最近的备份,并将其与备份时的内存数据模型进行比较,这应该是相同的。最明显的方法是在当前模型及其序列化然后反序列化的版本上应用.modal-content

问题在于,自定义数据结构的嵌套程度和数量需要大量代码才能编写所有这些.modal-backdrop {z-index: 1050;} .modal-content {z-index: 1060;} 实现。更不用说许多这些单独的实现只需很多行来比较每个成员的平等。我们很容易谈论> 1k行代码只花在operator==上。即使我们做了所有这些,程序员也会有很大的错误。

是否有快速和肮脏(尽管可靠)平等检查的替代方案,可能使用更低级别的技术,或者除了编写operator==函数之外什么都不需要做任何事情?

1 个答案:

答案 0 :(得分:2)

tie解决方案将是您最好的选择。

struct equal_by_tie {
  template<class T>
  using enable = std::enable_if_t<std::is_base_of<equal_by_tie, T>,bool>;
  template<class T>
  friend enable<T>
  operator==( T const& lhs, T const& rhs ) {
    return mytie(lhs) == mytie(rhs);
  }
  template<class T>
  friend enable<T>
  operator!=( T const& lhs, T const& rhs ) {
    return mytie(lhs) != mytie(rhs);
  }
};

现在你必须写

struct some_thing : equal_by_tie {
public:
  friend auto mytie( some_thing const& self ) {
    return std::tie( self.x, self.y, self.mem3 );
  }
};

并为您编写了==!=

目前还没有办法审核mytie是否写得正确,除了C ++ 17中的一些hackery,其实是不值得考虑的(结构化绑定,这是一个可怕的黑客,不要&#t; t问)。

可以减少mytie出错的可能性的一种方法是更多地使用

根据它实现swap(可能使用与上面operator==相同的父类技巧)。现在就operator=swap实施mytie。对friend std::size_t hash(Foo const&)执行相同的操作并将其挂钩到标准的哈希。

坚持mytie与数据声明的顺序相同,并将父实例绑定为子关系。编写一个函数,将您的系统结构/类对齐考虑在内,并计算 在<{1}}中的结构大小。静态断言constexprFoo的大小匹配。 (根据需要添加vtable等的软糖因子)。现在,在不触及calc_struct_size(tag<decltype(mytie(std::declval<Foo&>()))>)的情况下更改结构的布局会导致不好的事情发生。

mytie中的每对字段与指针不等式进行比较,以确保您不会重复相同的字段两次;尝试确保在运行时优化到mytie(因为你要在调试时检查这个问题,并且调试通常会关闭优化;也许这是一个断言你的独特情况想只在发布版本中执行!)。

你也想做一些健全检查。如果您的true包含原始指针mytie是错误的,智能指针也是如此;你希望你的==是一个深刻的平等。

为此,也许==错误的东西

==
但是,这会增加你的负担。但是我们的想法是增加可靠性,因为你已经注意到,很难有很多代码和许多错误点。

没有简单的方法可以做到这一点。

如果你的数据不是完全打包的普通旧数据,没有指针或虚函数或任何东西,那么memcmp是个坏主意。并且填充很容易进入代码,打破基于memcmp的平等;由于填充中的数据状态未定义,因此很难找到这样的braek。