Home > Net >  C : Within a Set or Map, can I determine that the KeyEqual predicate is equivalent to std::memcmp?
C : Within a Set or Map, can I determine that the KeyEqual predicate is equivalent to std::memcmp?

Time:01-10

Simple examples:

  • Arithmetic scalars: the result of KeyEqual is equivalent to comparing bit patterns, so effectively std::memcmp.
  • Pointer to null-terminated string: the result of KeyEqual is not equivalent to comparing pointer address; testing equality requires applying std::strcmp.

Can KeyEqual be queried / introspected in that way within a templated class?

CodePudding user response:

Basically std::memcmp is never used for comparision of objects. The problem is that objects can contain padding bits that doesn't affect objects value, but can have random value themselvs. So, two objects with same value can have diffirent object representation. Quote from here: https://en.cppreference.com/w/cpp/language/object

For an object of type T:

  • its object representation is the sequence of sizeof(T) objects of type unsigned char (or, equivalently, std::byte) (since C 17) beginning at the same address as the T object,
  • its value representation is the set of bits that hold the value of its type T, and
  • its padding bits are the bits in the object representation that are not part of the value representation.

Moreover some objects in C may have different "logical value" than its value representation in which case they overload comparison operators.

This is even mentioned in description of std:memcmp: https://en.cppreference.com/w/cpp/string/byte/memcmp

This function reads object representations, not the object values, and is typically meaningful for only trivially-copyable objects that have no padding. For example, memcmp() between two objects of type std::string or std::vector will not compare their contents, and memcmp() between two objects of type struct{char c; int n;} will compare the padding bytes whose values may differ when the values of c and n are the same.

CodePudding user response:

In general, no. What you are asking for might not be available to the compiler, or is otherwise equivalent to the halting problem.

The compiler might have only this, with the implementation in another translation unit.

struct KeyEqual {
    bool operator()(int lhs, int rhs);
};

You can test that it is std::equal_to<Key>, and that Key is either a scalar, or an array of scalar. That will miss classes whose data members are all scalars, but given struct Padded {char c; int n;}, std::equal_to<Padded> is not equivalent to std::memcmp.

But you shouldn't care. Just use KeyEqual directly.

  • Related