Последствия POD для структуры, содержащей контейнер стандартной библиотеки

Недавно я столкнулся с этим вопросом. Моя цель — понять, как компилятор C++ просматривает определения структур, содержащие стандартные библиотечные контейнеры, такие как std::vector.

В ответе Бена Фойгта на связанный вопрос цитируется следующее из стандарта C++0x:

....

Тривиальный класс — это класс, который имеет простой конструктор по умолчанию (12.1) и может быть легко скопирован.

[ Примечание. В частности, тривиально копируемый или тривиальный класс не имеет виртуальных функций или виртуальных базовых классов. — конец примечания ]

Класс стандартного макета — это класс, который:

  • не имеет нестатических членов данных класса нестандартного макета (или массива таких типов) или ссылки,

....

Я почти уверен, что выделенный жирным шрифтом текст означает, что следующее поведение не определено

struct A 
{
    std::vector< SomeType > myVec;
    int myC;  
    A( int c ) : myC : (c) {}
};

int main( void )
{
    A one( 1 );
    A two( 2 );

    SomeType k, z;
    one.myVec.push_back( k );
    two.myVec.push_back( z );

    memcpy( &two, &one, sizeof( A ) ); // bad juju
}

То же самое относится и к любому типу из стандартной библиотеки, включая более простые типы, такие как std::string. Это может быть связано с характером дизайна библиотеки, учитывая широкое использование наследования и программирования шаблонов.

Таким образом, хотя struct A будет напоминать тип POD, тот факт, что он содержит этот стандартный библиотечный тип, автоматически делает его недействительным из этой категории с точки зрения компилятора.

Верны ли мои предположения?


person zeboidlund    schedule 27.11.2014    source источник
comment
Нет, A нельзя просто скопировать. И ни std::vector, ни std::string я бы не назвал простыми. Некоторые стандартные библиотечные классы гарантированно легко копируются.   -  person T.C.    schedule 27.11.2014
comment
Стандартный макет и POD не имеют отношения к тому, о чем вы спрашиваете; A нельзя просто скопировать, и это является важным требованием.   -  person ildjarn    schedule 27.11.2014
comment
Это не только не POD с точки зрения компилятора, но и не с точки зрения стандарта; не все его члены легко копируются. Это не имеет ничего общего с макетом, наследованием, шаблонами или простотой.   -  person molbdnilo    schedule 27.11.2014
comment
Библиотека STL вообще-то безобидный ярлык, но здесь он вводит в заблуждение. STL была интегрирована в Стандартную библиотеку около 20 лет назад, но std::string, например, пришла откуда-то еще.   -  person MSalters    schedule 27.11.2014
comment
@MSalters Тем более с библиотекой STL. Поскольку это звучит так, как будто это неоднозначность, означающая STL, а не стандартную библиотеку (поскольку в противном случае аббревиатура была бы избыточной).   -  person    schedule 27.11.2014
comment
My goal is to understand how the C++ compiler views struct definitions Это предложение не имеет для меня особого смысла. Очевидно, что компиляторы интерпретируют стандарт по-разному и подвержены ошибкам. Аналогично с as far as the compiler is concerned. Если вам нужен ответ, который касается стандарта (а не конкретной реализации), зачем вы привносите в это компилятор? Кроме того, стандартная библиотека C++, компилятор и реализации стандартной библиотеки — это три разные вещи. Я думаю, что ваш вопрос нужно переформулировать.   -  person    schedule 27.11.2014


Ответы (1)


Нет. Ваши базовые предположения ошибочны. «Стандартный макет» не имеет отношения к шаблонам. Например. std::pair<T1, T2> имеет стандартную компоновку тогда и только тогда, когда и T1, и T2 имеют стандартную компоновку. То же самое касается std::array<T,N>

Однако ни один из контейнеров не имеет стандартного макета. Весь смысл их распределителей в том, чтобы иметь расширенное управление памятью.

person MSalters    schedule 27.11.2014
comment
Они могут быть, а могут и не быть стандартной компоновки. Они определенно не являются тривиально копируемыми. - person T.C.; 28.11.2014
comment
@Т.С. std::array хотя и static_assert(std::is_pod<std::array<int, 1>>()) проходит GCC 6.4, см. также: stackoverflow.com/questions/3674247/ - person Ciro Santilli 新疆再教育营六四事件ۍ 26.10.2018