тривиальные и стандартные раскладки и РМО


в терминах непрофессионала, в чем разница между тривиальными типами, стандартными типами компоновки и стручками?

в частности, я хочу определить, является ли new T отличается от new T() для любого параметра шаблона T. Какая из черт типа is_trivial,is_standard_layout и is_pod должен ли я выбрать?

(как побочный вопрос, Может ли любая из этих черт типа быть реализована без магии компилятора?)

2 61

2 ответа:

Я не думаю, что это можно сделать в термины неспециалиста, по крайней мере, без много дополнительные объяснения. Одним из важных моментов является статическая и динамическая инициализация, но объяснение этого непрофессионалу будет несколько страниц само по себе...

стручки были (mis-)определены в C++98. На самом деле есть два отдельных намерения, которые не очень хорошо выражены: 1) что если вы скомпилируете объявление структуры C в C++, то что вы получите, должно быть эквивалентно тому, что у Вас было в C. 2) стручок будет только когда-либо нужна/использовать статическую (не динамическую) инициализацию.

C++0x / 11 отбрасывает обозначение "POD" (почти) полностью, в пользу "тривиальной" и "стандартной компоновки". Стандартная компоновка предназначена для захвата первого намерения - создание чего-то с макетом, таким же, как и в C. Trivial, предназначено для захвата поддержки статической инициализации.

С new T и new T() имеет дело с инициализацией, вы наверное хочу is_trivial.

Я не уверен, что требуется магия компилятора. Моя немедленная реакция была бы, вероятно, да, но, зная некоторые вещи, которые люди сделали с TMP, мне трудно быть уверенным, что кто-то не может этого сделать...

Edit: для примеров, возможно, лучше всего просто процитировать примеры из N3290:

struct N { // neither trivial nor standard-layout
   int i;
   int j;
    virtual ~N();
};

struct T { // trivial but not standard-layout
    int i;
private:
    int j;
};

struct SL { // standard-layout but not trivial
    int i;
    int j;
    ~SL();
};

struct POD { // both trivial and standard-layout
    int i;
    int j;
};

как вы, несомненно, догадываетесь,POD также является стручковой структурой.

для типов стручков new T() значение-инициализация(значение-инициализировать все члены) ,и new T не инициализирует члены (по умолчанию-инициализация). Для различий между различными формами инициализации посмотреть здесь. Итог: вам нужно is_pod.