2011-10-08 8 views
5

Se supone que AFAIK, boost::compressed_pair asegura que la dirección del primer y segundo memebrs sea diferente mientras hace su magia de comprimir el par. Lo dice here. Parece que no es el caso y su comportamiento es diferente en diferentes compiladores. Estoy usando boost v 1.47. ¿Qué me estoy perdiendo?boost compressed_pair y direcciones de objetos vacíos

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()); 

Respuesta

5

Cuando los tipos son diferentes y uno o ambos de los tipos es una clase vacía, los subobjetos se supone que deben estar en la misma dirección (si el compilador puede tirar de la optimización de la clase base vacía apagado), que es la punto del par comprimido.

Cuando los tipos son los mismos, creo una nota del capítulo 10 de la norma se aplica:

Una base subobjeto clase puede ser de cero tamaño (cláusula 9); sin embargo, dos subobjetos que tienen el mismo tipo de clase y que pertenecen al mismo objeto derivado no se deben asignar a la misma dirección (5.10).

Parece que le corresponde al compilador asegurarse de que están asignados a direcciones diferentes (y VC10 podría estar equivocándose).

Los comentarios en el encabezado del impulso indican que antes no se molestaron en poner dos instancias diferentes de la misma clase vacía en el par comprimido. En cambio, simplemente almacenaron una instancia y tanto first() como second() devolvieron el mismo objeto.

// 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). 
Cuestiones relacionadas