Как новое размещение узнает, какой макет создать?
#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
Есть ли раздел вСтандарт C ++ 14 что требует «нового» для создания определенного макета? Есть ли гарантия, что созданный новый макет помещается в буфер размера sizeof (B) и со смещением ноль?
редактировать: не могли бы вы использовать grep-friendly терминологию или предоставить ссылки? Я добавил ссылку на стандарт на вопрос.
Примите во внимание приведенный выше пример вывода: что говорит вам число 24? Какой размер буфера?
В стандарте может быть утверждение, что наиболее производный объект всегда является прямой непрерывной копией представления объекта, но я не нашел этого.
Что мы знаем о новом, так это то, что он должен использоваться с полным типом объекта. [Expr.new]
Есть пример для выражения new с опцией размещения в [class.dtor] §12.4 (14). Однако пример может сработать просто потому, что класс в нем имеет стандартную компоновку.