Вопрос по c++ – Каково основное использование align_storage?

10

Каково основное использование std :: tr1 :: align_storage? Можно ли использовать его как автоматическую память для типа данных Foo, подобного приведенному ниже?

   struct Foo{...};
   std::tr1::aligned_storage<sizeof(Foo)
        ,std::tr1::alignment_of<Foo>::value >::type buf;
   Foo* f = new (reinterpret_cast<void*>(&buf)) Foo();
   f->~Foo();

Если так, то как насчет хранения нескольких Foo в буфере, как,

    std::tr1::aligned_storage<5*sizeof(Foo)
            ,std::tr1::alignment_of<Foo>::value >::type buf;
    Foo* p = reinterpret_cast<Foo*>(&buf);
    for(int i = 0; i!= 5; ++i,++p)
    {
        Foo* f = new (p) Foo();
    }

Это действительные программы? Есть ли другой вариант использования для этого? Поиск в Google дает только документацию о align_storage, но очень мало об ее использовании.

Ваш Ответ

1   ответ
9

reinterpret_cast, это выглядит нормально для меня. (Я не уверен на 100% во втором).

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

Насколько я знаю, переносимое решение для приведения указателя x к типу T * - этоstatic_cast<T*>(static_cast<void*>(x)), посколькуstatic_cast к и отvoid* гарантирует указатель на тот же адрес.

Но это только косвенно связано с вашим вопросом. :)

Это хорошее решение. static_cast to / from void * - это нормально, но верно ли это для нескольких static_cast, таких как static_cast <T> (static_cast <void *> (x)), где x имеет тип? Затем я заменю все свое приведение типа X на тип Y как два static_cast вместо одного reinterpret_cast, чтобы чувствовать себя безопаснее. (Компилятор, который я использую GCC & MSVC 9, не причиняет никакого вреда reinterpret_cast, и я не уверен, что другой сделает это. Но да, я хочу быть на более безопасной стороне :)) abir
yeah, я не знаю компилятора, где переинтерпретация на самом деле является проблемой (и я думаю, что они заставят его работать так, как вы ожидаете в C ++ 0x), но согласно стандарту, он не определен поведение. Трюк static_cast должен работать для любого типа указателя. jalf
template<typename T> T pointer_cast(void* p) { return static_cast<T>(p); }. Это, плюс константная версия с перегрузкой const void* p), сэкономит при наборе текста. Boost имеет аналогичные функции,static_pointer_cast а такжеdynamic_pointer_cast. Logan Capaldo
на самом деле, как в текущем, так и в (черновом) стандарте C ++ 1x,reinterpret_cast в или изvoid* не допускается (несмотря на то, что реализации это разрешают). так что вы действительно должны использоватьstatic_cast. В C ++ 1x, для стандартных типов макетов,reinterpret_cast<T*>(u) определяется в терминахstatic_cast<T*>(static_cast<void*>(u)). Johannes Schaub - litb
Так как ты судилreinterpret_cast чтобы быть проблематичным, могу ли я спросить, почему, и (вопрос с подвохом?), как еще можно отобразитьaligned_storage фактическому типу? И да, в C ++ 11,reinterpret_cast (для большинства, если не для всех типов) эквивалентно цепочкеstatic_cast S. underscore_d

Похожие вопросы