Define generic comparison operator
我想出了一个主意,定义一个通用的比较运算符,它可以与任何类型一起工作,这很有趣。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <cstring> #include <iostream> class A { public: A(int id) : id(id) {} private: int id; }; template <class T> inline bool operator==(const T& a, const T& b) { return memcmp(&a, &b, sizeof(a)) == 0; // implementation is unimportant (can fail because of padding) } int main() { std::cout << (A(10) == A(10)) << std::endl; // 1 std::cout << (A(10) == A(15)) << std::endl; // 0 } |
我认为这可以帮助解决C++中缺省比较运算符的不足。
这是个可怕的主意吗?我想知道这样做是否会在某些情况下破坏任何东西?
这样做确实是个糟糕的主意。
如果某个类型未定义相等运算符,则很可能是因为您无法合理地比较该类型的两个对象以实现相等。
即使对于缺少的相等运算符是实现者的监督的情况,您将想到的任何"全部捕获"实现都极不可能做一些明智的事情。
所以总结一下:不要这样做!编译时错误比运行时错误要好;不要过早地添加一个最有把握的"解决方案",以隐藏实际问题,而是在发生编译时添加实际的解决方案。
?对于初学者,您提出的解决方案对于带有填充的类型、带有重载一元
让我们上一个完全正常的课,比如说
现在比较两个。显然,
相等性是由类语义定义的,而不是由对象内直接的位定义的。
是的,这是一个可怕的想法:如果指针未初始化:下面是一个失败的示例(因此此代码有两个不同的输出):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <cstring> #include <iostream> class A { public: A(int id) : id(id) {} private: int id; A* a; }; template <class T> inline bool operator==(const T &a, const T &b) { return memcmp(&a, &b, sizeof(a)) == 0; } int main() { std::cout << (A(10) == A(10)) << std::endl; // 1 std::cout << (A(10) == A(15)) << std::endl; // 0 } |
输出:
1 2 | 0 0 |
对于两个指针,RAM初始内容的两个相同值的可能性非常小,那么另一个输出是:
1 2 | 1 0 |
略微说一下,我知道为具有大量成员的类编写相等运算符的最好方法是使用这个思想(此代码需要C++ 14):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <tuple> struct foo { int x = 1; double y = 42.0; char z = 'z'; auto members() const { return std::tie(x, y, z); } }; inline bool operator==(const foo& lhs, const foo& rhs) { return lhs.members() == rhs.members(); } int main() { foo f1; foo f2; return f1 == f2; } |
编译器资源管理器上的代码