提升compressed_pa​​ir和空对象的地址

Sum*_*ant 6 c++ optimization boost

AFAIK,boost :: compressed_pa​​ir应该确保第一个和第二个memebrs的地址是不同的,同时它可以实现压缩该对的魔力.它在这里说.看起来并非如此,并且它的行为在不同的编译器上是不同的.我正在使用boost v 1.47.我错过了什么?

struct E1 {};
struct E2 {};

boost::compressed_pair<E1, E2> diff_pair;
boost::compressed_pair<E1, E1> same_pair;

// clang++ and g++ 4.7 print the same address but VC2010 prints different addresses.
printf("different pairs = %p, %p\n", &diff_pair.first(), &diff_pair.second());

// clang++ and g++ 4.7 print different addresses but VC2010 prints the same address.
printf("different pairs = %p, %p\n", &same_pair.first(), &same_pair.second());
Run Code Online (Sandbox Code Playgroud)

Unc*_*ens 7

当类型不同并且一个或两个类型是空类时,子对象应该位于相同的地址(如果编译器可以关闭空基类优化),那就是压缩对的点.

当类型相同时,我认为标准第10章的注释适用:

基类子对象可以是零大小(第9条); 但是,必须不在同一地址(5.10)分配具有相同类类型且属于同一最多派生对象的两个子对象.

因此,似乎由编译器来确保它们被分配在不同的地址(并且VC10可能会出错).

boost的标题中的注释表明,早些时候他们根本不打算在压缩对中放置相同空类的两个不同实例.相反,他们只存储了一个实例和两个实例first()second()返回了相同的对象.

   // 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).
Run Code Online (Sandbox Code Playgroud)