Если вы не против потратить немного ОЗУ, вы можете сделать класс оболочки aligned_holder, который гарантирует, что объект, который он удерживает, будет выровнен с любой границей выравнивания, которую вы укажете. (Обратите внимание, что количество неиспользуемого ОЗУ равно заданной границе выравнивания)
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <new>
// Makes sure that its held object is always aligned to the specified alignment-value,
// at the cost of using up some extra RAM.
template<class T, int AlignTo=16> class aligned_holder
{
public:
aligned_holder()
{
new (getAlignedPointer()) T();
}
~aligned_holder()
{
getAlignedObject().~T();
}
T & getAlignedObject() {return *reinterpret_cast<T*>(getAlignedPointer());}
const T & getAlignedObjectConst() const {return *reinterpret_cast<const T*>(getAlignedPointerConst());}
private:
char * getAlignedPointer()
{
const ptrdiff_t offset = intptr_t(_buf)%AlignTo;
return &_buf[(intptr_t)(AlignTo-offset)];
}
const char * getAlignedPointerConst() const
{
const ptrdiff_t offset = intptr_t(_buf)%AlignTo;
return &_buf[(intptr_t)(AlignTo-offset)];
}
char _buf[AlignTo+sizeof(T)];
};
... и модульное тестирование, к (надеюсь) убедиться, что я не испортит пример:
class IWannaBeAligned
{
public:
IWannaBeAligned()
{
const intptr_t iThis = (intptr_t)(this);
if ((iThis % 16) != 0) printf("Error! object %p is not 16-byte aligned! (offset=%ld)\n", this, iThis%16);
else printf("Good, object %p is 16-byte aligned.\n", this);
}
~IWannaBeAligned()
{
printf("Deleting object %p\n", this);
}
char buf[32]; // just to give it a more realistic object size than one byte
};
int main()
{
{
printf("First, let's try it without the aligned_holder:\n");
IWannaBeAligned notAligned;
}
printf("\n");
{
printf("Now, we'll try it with the aligned_holder:\n");
aligned_holder<IWannaBeAligned> isAligned;
}
return 0;
}
У членов класса гарантируются требования к их выравниванию в локальных или статических переменных, а также в локальных или статических массивах. Если вы динамически выделяете память, вы можете столкнуться с проблемами. Я предполагаю, что вы пытаетесь использовать 'std :: vector' или аналогичный? Если да, скажите так. –
Вы правы, я пытаюсь использовать вектор такого класса, как этот. Любые рекомендации? – MNagy
Вы не можете «выровнять элементы», не выровняв весь класс с одинаковым значением. В противном случае вы можете просто вытеснить весь объект с помощью разрешенного выравнивания класса и сломать выравнивание элемента. (Разметка класса, конечно, исправлена и не определена для каждого объекта.) –