What type will make “std::has_unique_object_representations” return false?

老子叫甜甜 提交于 2019-12-04 03:40:47

Understanding the purpose of this trait requires understanding the distinction between an objects "value representation" and its "object representation". From the standard:

The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T). The value representation of an object is the set of bits that hold the value of type T . For trivially copyable types, the value representation is a set of bits in the object representation that determines a value, which is one discrete element of an implementation-defined set of values.

So, object representation is the total storage of an object. But consider the following object:

struct T
{
  char c;
  int i;
};

On many systems, sizeof(T) will be 8. Why? Because int has to be 4-byte aligned, so the compiler inserts 3 bytes of padding between c and i. Since those three bytes are part of the object's storage (based on sizeof(T)), they are part of the object's object representation.

But those three bytes are not part of its value representation. If you modified those bytes, they would not affect the values of c or i, or anything else about them.

If you wrote an operator== overload for T, changes to those bytes would not affect its results. Which also means that if you did write an operator== overload, it could not be implemented like this:

bool operator==(const T &lhs, const T &rhs)
{
  return std::memcmp(&lhs, &rhs, sizeof(T)) == 0;
}

Why not? Because two Ts can have different values for those padding bytes, but still have the same value of c and i. And thus they have the same value representation and thus should be considered equivalent.

has_unique_object_representations is true when T's object representation and its value representation exactly overlay one another (and when T is trivially copyable). So, when would you care about this?

You can write a generalized hashing function that works on any trivially copyable type T by reading its value representation as an array of bytes and hashing them. Well, you could do that, but only if the type doesn't have padding bytes. And that's what has_unique_object_representations tells you: that all of the bytes in the object representation matter.

Also, note that float types, won't necessarily have this value be true, since binary equality and floating-point equality aren't the same thing in IEEE-754. So types which contain floats will also not necessarily have this be true. Indeed, implementations that use one's-complement signed integers, or signed integers with trap representations, will also not have this be true for such types.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!