gpt4 book ai didi

c++ - 这是实现通用 operator== 和 operator< 的安全方法吗?

转载 作者:可可西里 更新时间:2023-11-01 14:58:58 26 4
gpt4 key购买 nike

看到this question之后,我的第一个想法是定义通用等价和关系运算符是微不足道的:

#include <cstring>

template<class T>
bool operator==(const T& a, const T& b) {

return std::memcmp(&a, &b, sizeof(T)) == 0;

}

template<class T>
bool operator<(const T& a, const T& b) {

return std::memcmp(&a, &b, sizeof(T)) < 0;

}

using namespace std::rel_ops然后会变得更有用,因为它会被运算符的默认实现完全通用 ==< .显然,这不会执行成员比较,而是按位比较,就好像该类型只包含 POD 成员一样。这与 C++ 生成复制构造函数的方式并不完全一致,例如,确实执行成员复制。

但是我想知道上面的实现是否真的安全。这些结构自然会有相同的填充,属于相同的类型,但是填充的内容是否保证相同(例如,填充为零)?有什么原因或在什么情况下这不起作用?

最佳答案

不——举个例子,如果你有 T==(float | double | long double),你的 operator==不能正常工作。两个 NaN 永远不应该比较为相等,即使它们具有相同的位模式(事实上,检测 NaN 的一种常用方法是将数字与其自身进行比较——如果它不等于自身,则它是 NaN)。同样,两个指数中所有位都设置为 0 的 float 具有值 0.0(准确),而不管尾数中的哪些位可能被设置/清除。

你的 operator<正确工作的机会就更少了。例如,考虑 std::string 的典型实现看起来像这样:

template <class charT>
class string {
charT *data;
size_t length;
size_t buffer_size;
public:
// ...
};

按照成员的顺序,您的 operator<将根据字符串恰好存储其数据的缓冲区地址进行比较。例如,如果它恰好是用 length 编写的成员优先,您的比较将使用字符串的长度作为主键。在任何情况下,它都不会根据实际字符串内容进行比较,因为它只会查看 data 的值。指针,而不是它指向的任何内容,这是您真正想要/需要的。

编辑:就填充而言,不要求填充的内容相等。理论上,填充也可能是某种陷阱表示,如果您甚至尝试查看它,它会导致信号、抛出异常或类似顺序的东西。为避免此类陷阱表示,您需要使用类似强制转换的方法将其视为 unsigned char 的缓冲区。秒。 memcmp可能会那样做,但又可能不会......

另请注意,相同类型的对象并不必然意味着使用相同的成员对齐方式。这是一种常见的实现方法,但编译器也完全有可能根据它“认为”特定对象的使用频率来使用不同的对齐方式,并在 in 表示此特定实例对齐方式的对象(例如,写入第一个填充字节的值)。同样,它可以按(例如)地址分隔对象,因此位于偶数地址的对象具有 2 字节对齐,位于四的倍数的地址具有 4 字节对齐,依此类推(这不能用于 POD 类型,但除此之外,所有投注均无效)。

这些都不太可能也不常见,但我也想不出标准中有任何禁止它们的地方。

关于c++ - 这是实现通用 operator== 和 operator< 的安全方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3610065/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com