When the types are different and one or both of the types is an empty class, the subobjects are supposed to be at the same address (if the compiler can pull the empty base class optimization off), that's the point of the compressed pair.
When the types are the same, I think a note from chapter 10 in the standard applies:
A base class subobject may be of zero size (Clause 9); however, two
subobjects that have the same class type and that belong to the same
most derived object must not be allocated at the same address (5.10).
So it seems it is up to the compiler to ensure that they are allocated at different addresses (and VC10 might be getting it wrong).
The comments in the boost's header indicate, that earlier they didn't bother to put two different instances of the same empty class in the compressed pair at all. Instead they just stored one instance and both first()
and second()
returned the same object.
// 4 T1 == T2, T1 and T2 both empty
// Originally this did not store an instance of T2 at all
// but that led to problems beause it meant &x.first() == &x.second()
// which is not true for any other kind of pair, so now we store an instance
// of T2 just in case the user is relying on first() and second() returning
// different objects (albeit both empty).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…