На месте фабрики и неинициализированное пространство: если разрешение на строительство было разрешено

давайте рассмотрим этот дополнительный документ:
http://www.boost.org/doc/libs/1_35_0/libs/utility/in_place_factories.html

экстракт:

struct C
{
template<class InPlaceFactory>
C ( InPlaceFactory const& aFactoty )
:
contained_ ( uninitialized_storage() )
{
aFactory.template apply<X>(contained_);
}

char* uninitialized_storage() { return new char[sizeof(X)] ; }

char* contained_ ;
} ;

Фактически, поскольку компилятор C ++ вызывает конструкторы членов класса во время списка инициализации, мы не можем расширять аргументы фабрики на месте без некоторого препроцессора (или прекомпилятора). Поэтому, чтобы избежать вызова конструктора по умолчанию, мы меняем тип члена на char*,

Я утверждаю, что это грустно.

Представь это contained_ был намеченного типа X:

разве нет способа предотвратить вызов конструктора вообще? ? Переводим элемент в неинициализированное состояние, так же, как если бы это был просто пул байтов с правильными требованиями к пространству и выравниванию для типа, и тогда мы можем вызывать нужные нам конструкторы, используя placement new (что именно делает фабрика на месте)?

Таким образом, у нас не будет проблем с выравниванием или читаемостью, потому что «что может быть сохранено в этом char* ? без разницы»

И мы могли бы использовать нотацию фабрики на месте, но через X типа, а не char* тип.

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

Вы заметили, что оригинальное решение для повышения использует new извлечь выгоду из 16-байтового выравнивания (32 байта для объектов размером более 4096 в Microsoft CRT 2014). Эффективно избегая проблем выравнивания, вызванных иначе более естественной нотацией, которая была бы:

char contained_[sizeof(X)];

Конечно, «исправить» можно было бы использовать что-то вроде __declspec(align(alignof(X))) до объявления contained_, но, как я уже сказал, использование массивов символов вряд ли является приемлемым решением, заставляющим нас выполнять приведение каждый раз, когда мы хотим использовать contained_

Спасибо !

0

Решение

Задача ещё не решена.

Другие решения