我有一个非常大的数据模型,有许多成员,其中许多本身就是大数据模型,在这几个层次上都有这样的嵌套。顶级类表示序列化并发送到服务器进行备份的整体模型。作为调试步骤,我们希望反序列化最近的备份,并将其与备份时的内存数据模型进行比较,这应该是相同的。最明显的方法是在当前模型及其序列化然后反序列化的版本上应用.modal-content
。
问题在于,自定义数据结构的嵌套程度和数量需要大量代码才能编写所有这些.modal-backdrop {z-index: 1050;}
.modal-content {z-index: 1060;}
实现。更不用说许多这些单独的实现只需很多行来比较每个成员的平等。我们很容易谈论> 1k行代码只花在operator==
上。即使我们做了所有这些,程序员也会有很大的错误。
是否有快速和肮脏(尽管可靠)平等检查的替代方案,可能使用更低级别的技术,或者除了编写operator==
函数之外什么都不需要做任何事情?
答案 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}}中的结构大小。静态断言constexpr
和Foo
的大小匹配。 (根据需要添加vtable等的软糖因子)。现在,在不触及calc_struct_size(tag<decltype(mytie(std::declval<Foo&>()))>)
的情况下更改结构的布局会导致不好的事情发生。
将mytie
中的每对字段与指针不等式进行比较,以确保您不会重复相同的字段两次;尝试确保在运行时优化到mytie
(因为你要在调试时检查这个问题,并且调试通常会关闭优化;也许这是一个断言你的独特情况想只在发布版本中执行!)。
你也想做一些健全检查。如果您的true
包含原始指针,mytie
是错误的,智能指针也是如此;你希望你的==
是一个深刻的平等。
为此,也许==
是错误的东西。
==
但是,这会增加你的负担。但是我们的想法是增加可靠性,因为你已经注意到,很难有很多代码和许多错误点。
没有简单的方法可以做到这一点。
如果你的数据不是完全打包的普通旧数据,没有指针或虚函数或任何东西,那么memcmp是个坏主意。并且填充很容易进入代码,打破基于memcmp的平等;由于填充中的数据状态未定义,因此很难找到这样的braek。