如何在不破坏聚合类初始化语法的前提下使用boost::equality_comparable?
嘿,这个问题我之前也踩过坑!核心矛盾很明确:一旦让你的聚合类Agg继承boost::equality_comparable<Agg>,在旧版C标准里它就不再是聚合类了,原来那种简洁的初始化语法直接就失效了。不过别慌,有几个不同的方案能解决,看你这边的C版本和技术栈限制:
最省心的方案:升级到C++17或更高版本
C++17对聚合类的定义做了关键扩展——允许聚合类继承public、非虚的空基类,只要基类本身符合聚合类的要求(没有用户声明的构造函数、析构函数,也没有虚函数这些)。而boost::equality_comparable<Agg>本质就是一个空的CRTP基类,完全满足这个条件。
升级之后,你的Agg类在继承boost的这个基类后仍然是聚合类,原来的Agg{1}这种初始化语法可以直接用,编译器会自动隐式初始化那个空基类部分,根本不需要加额外的{}。这样既保留了boost自动生成operator!=的便利,又不用修改任何现有代码。如果能上C++20,直接抛弃boost的依赖
C++20里标准库直接支持默认生成operator!=了!你完全不需要依赖boost::equality_comparable,只要在你的Agg类里加上一行代码就行:bool operator!=(const Agg&) const = default;编译器会自动根据你已经写好的
operator==生成正确的operator!=,代码更简洁,还不用依赖第三方库,同时聚合类的初始化特性也完全不受影响。没法升级C++版本的退而求其次方案:自己写一行operator!=
如果你因为项目限制没法升级C++版本,那其实自己写operator!=真的没什么负担——毕竟逻辑超简单,和boost::equality_comparable生成的代码完全一致:friend bool operator!=(const Agg& lhs, const Agg& rhs) { return !(lhs == rhs); }这一行代码不会对聚合类的初始化语法造成任何破坏,维护成本几乎为零,完全可以替代boost的功能。
内容来源于stack exchange

