Como o canal novo sabe qual layout criar?
#include <iostream>
#include <typeinfo>
struct A { int a; };
struct B : virtual A { int b; };
struct C : virtual A { int c; };
struct D : B,C { int d; };
int main()
{
D complete;
B contiguous;
B & separate = complete;
B * p[2] = {&separate, &contiguous};
// two possible layouts for B:
std::cout<< (int)((char*)(void*) &p[0]->a -(char*)(void*)&p[0]->b)<<" "<< sizeof(*p[0])<< "\n";
std::cout<< (int)((char*)(void*) &p[1]->a -(char*)(void*)&p[1]->b)<<" "<< sizeof(*p[1])<< "\n";
alignas(B) char buff[sizeof(B)];
void * storage = static_cast<void*>(buff);
// new expression skips allocation function:
auto pointer= new (storage) B; // Which layout to create?
std::cout << typeid(pointer).name()<<"\n";
pointer->~B(); // Destructor knows layout through typed pointer.
}
// sample output (Debian 8, amd64):
// 24 16
// 4 16
// P1B
Existe uma seção noPadrão C ++ 14 que exige 'novo' para criar um layout específico? Existe garantia de que o layout criado por novos se encaixe em um buffer de tamanho sizeof (B) e com deslocamento zero?
edit: Você poderia usar a terminologia amigável ao grep ou fornecer referências? Eu adicionei uma referência ao padrão à pergunta.
Leve em consideração a amostra de saída acima: O que o número 24 diz a você? Qual é o tamanho do buffer?
Pode haver uma declaração no padrão de que um objeto mais derivado é sempre uma cópia direta e contígua da representação do objeto, mas não encontrei esse.
O que sabemos sobre o novo é que ele deve ser usado com um tipo de objeto completo. [expr.new]
Há um exemplo para uma nova expressão com a opção de posicionamento no [class.dtor] §12.4 (14). No entanto, o exemplo pode funcionar simplesmente porque a classe é de layout padrão.