Является ли это безопасным способом реализации универсальных операторов operator == и operator

После просмотра этого вопроса я первой подумал, что было бы тривиально определить общую эквивалентность и реляционную операторы:

#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;

}

с использованием пространства имен std :: rel_ops стало бы еще более полезным, поскольку оно стало бы полностью универсальным с помощью реализаций по умолчанию операторов == и < . Очевидно, что при этом выполняется не поэлементное сравнение, а побитовое сравнение, как если бы тип содержит только члены POD. Это не полностью согласуется с тем, как C ++ генерирует конструкторы копирования, например, которые выполняют поэлементно. копирование.

Но мне интересно, действительно ли вышеупомянутая реализация безопасна. иметь одинаковую упаковку, одного типа, но гарантированно ли содержимое заполнения идентично (например, заполнено нулями)? Есть ли какие-либо причины или ситуации, в которых это не сработает?

12
задан Community 23 May 2017 в 12:22
поделиться

2 ответа

Многое может зависеть от вашего определения эквивалентности.

напр. если какие-либо члены, которые вы сравниваете в своих классах, являются числами с плавающей запятой.

Вышеупомянутая реализация может рассматривать два числа типа double как неравные, даже если они получены в результате одного и того же математического вычисления с одними и теми же входными данными, поскольку они могут не генерировать точно такие же выходные данные, а скорее два очень похожих числа.

Обычно такие числа следует сравнивать в числовом виде с соответствующим допуском.

0
ответ дан 2 December 2019 в 06:24
поделиться

Любая структура или класс, содержащие один указатель, сразу же не смогут пройти какое-либо осмысленное сравнение. Эти операторы будут работать ТОЛЬКО для любого класса Plain Old Data или POD. Другой ответчик правильно указал с плавающей запятой как на случай, когда даже это неверно, и байты заполнения.

Краткий ответ: если бы это была разумная идея, в языке она была бы похожа на конструкторы копирования/операторы присваивания по умолчанию.

0
ответ дан 2 December 2019 в 06:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: