0

I would like to know the best way to define a std::array type with with the additional feature of memory alignment using modern C++11. I understand that alignas cannot be used with type aliases but this is the spirit of what I'm trying to do:

template<class T, std::size_t N, std::size_t A>
using AlignedArray = alignas(A) std::array<T, N>;

which could be instanted like this:

AlignedArray<int8_t, 4, 32> MyArray;

The best working version I could come up with is this:

template<class T, std::size_t N, std::size_t A>
struct alignas(A) AlignedArray : std::array<T, N> {
    using std::array<T, N>::array;
};

Can anyone suggest anything simpler or better? I'm new to memory alignment issues so any advice would be appreciated.

As was noted in an earlier question, you can do this of course:

alignas(32) std::array<int8_t, 4> MyArray;

But that does not define a reusable type so it isn't what I'm looking for in this question.

atb
  • 1,412
  • 1
  • 14
  • 30
  • I would have though `std::array` already guaranteed it's elements' alignments are correct. – François Andrieux Jan 11 '19 at 20:27
  • 2
    Possible duplicate : https://stackoverflow.com/questions/39058850/how-to-align-stdarray-contained-data Though I'm not sure if this is what you are asking. – François Andrieux Jan 11 '19 at 20:27
  • @FrançoisAndrieux, maybe? But I may need a larger alignment size then it would guarantee, see the example. – atb Jan 11 '19 at 20:29
  • @RSahu That shows how to override the alignement of the type when declaring an aligned variable. atb asked for an aligned type. – eerorika Jan 11 '19 at 20:33
  • Are you actually restricted to C++11? In 17, aggregates can have bases, which makes your "best working version" better. – Yakk - Adam Nevraumont Jan 11 '19 at 20:37
  • @Yakk-AdamNevraumont, I could use C++14 it that helps. I would be interested in 17/21 answers for educational purposes as well. – atb Jan 11 '19 at 20:37
  • 3
    Do you want to align an array, or elements of the array? Not the same thing... – SergeyA Jan 11 '19 at 20:40
  • You're right, thank you. I'm going to close this question and perhaps reformulate it. – atb Jan 11 '19 at 20:49

1 Answers1

3

What's your goal? For any given T, std::array will ensure the right alignment. If you need overalign your types tough, you have to change the alignment of T itself - otherwise only the first array element would be overaligned:

alignas(64) std::array<int8_t, 16> a; // array[0] is overaligned, array[1] is not

struct OveralignedNum
{
  alignas(64) int8_t value;
};

std::array<OveralignedNum, 16> b; // every element is overaligned
erenon
  • 18,838
  • 2
  • 61
  • 93
  • 1
    @atb Wait, what? Overalignment is usually about feeding data to SIMD, and SIMD cares that the *first* element is overaligned and the rest packed. Are you overaligning for a non-SIMD reason? – Yakk - Adam Nevraumont Jan 11 '19 at 21:03
  • @Yakk-AdamNevraumont, yes, I was confused. My my original question is valid I suppose but not useful. – atb Jan 11 '19 at 22:57