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 typeunsigned char
(or, equivalently,std::byte
) (since C 17) beginning at the same address as theT
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 typestd::string
orstd::vector
will not compare their contents, andmemcmp()
between two objects of typestruct{char c; int n;}
will compare the padding bytes whose values may differ when the values ofc
andn
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.