C++ class for aligning objects on the stack
Silent bug: Bad move constructor

Your move constructor will perform a copy because your parameter is aligned_type const&amp;&amp;; you cannot move from a const value because moving implies modifying what you're moving from. Simply change the signature to:

aligned(aligned_type &amp;&amp;other);
//      ^^^^^^^^^^^^^^^ no more const


Bug: Bad dereference operator

Your dereference operator is defined like so:

T operator*() const {
// we don't really want to copy the value out every single time we deref, do we?
  return *ptr_;
}


It simply returns T, it should return T&amp;. Note that this is a source of a bug in your code. You end up creating a temporary when you assign by using the dereference operator. This can (and did on my system) result on a crash due to the memory access violation.

Only align to alignments that are powers of 2.

Your test code aligns to 7 and 13.

From [basic.align] in the C++ Standard (emphasis mine):


  Alignments are represented as values of the type std​::​size_­t. Valid
  alignments include only those values returned by an alignof expression
  for the fundamental types plus an additional implementation-defined
  set of values, which may be empty. Every alignment value shall be a
  non-negative integral power of two.


T* aligned_position();

This function is used in only one place. Unless you've got plans of using it elsewhere, I recommend erasing it and simply putting the code at the relevant location.

You don't have to index into the first element to get the address. You can use the fact that arrays decay to pointers.

uint8_t *p = storage_; // equivalent to uint8_t *p = &amp;storage_[0];


However, there is a faster way than looping in order to align an address to some boundary:

auto aligned_position() const noexcept
{
    return reinterpret_cast&lt;T*&gt;(
        (reinterpret_cast&lt;std::uintptr_t&gt;(&amp;storage_) + Align - 1) &amp; ~(Align - 1));
}


Do we really need aligned_position(); and ptr_?

No. Here is an alternative solution:

You currently allocate Align - 1 + sizeof(T) bytes. This is wasteful. You can use exactly as much space as you need by declaring your storage any of these two ways:


alignas(Align) std::uint8_t storage_[sizeof(T)];
std::aligned_storage_t&lt;sizeof(T), Align&gt; storage_; // from the &lt;type_traits&gt; header


Option 1 might be preferable because option 2 is not guaranteed to align to your requested boundary if Align &gt; alignof(std::max_align_t). In such a case, it will depend on the implementation of the standard library you're using; the Microsoft implementation does this.

Before: sizeof(aligned&lt;8, double&gt;) == 20

After: sizeof(aligned&lt;8, double&gt;) == 16

Wait, we're not done yet. We shouldn't align to the specified alignment blindly either because we can then specify an alignment of 4 for a double, which requires 8. Unaligned data like that becomes very slow to access (two reads instead of one) or can simply not work (crash) in certain systems.

The fix:

alignas(Align &lt; alignof(T) ? alignof(T) : Align) std::uint8_t storage_[sizeof(T)];


Note that we no longer need ptr_ because the first byte of storage_ now corresponds to a properly aligned byte for our type.

Before: sizeof(aligned&lt;8, double&gt;) == 20

After: sizeof(aligned&lt;8, double&gt;) == 8

We save quite a bit of space. In fact, with this solution, your class takes no more space than a T when aligned to alignof(T). You have to replace all uses of ptr_ with an appropriate statement; I recommend replacing all instances of ptr_ with a call to get(). This call will almost surely be optimized away.

Provide non-const versions of your accessor/modifier functions.

You want your type to be usable in non-const contexts, so provide non-const overloads for your operations. For example, define get() like so:

T* get() noexcept {
    return reinterpret_cast&lt;T*&gt;(&amp;storage_);
}

T const* get() const noexcept {
    return reinterpret_cast&lt;T const*&gt;(&amp;storage_);
}


You can provide this functionality wherever needed.



Final thoughts:


The class is basically a wrapper around a aligned_storage&lt;&gt; like storage. However, it is a good learning experience I suppose.
I've left out basic language features advice such as declaring functions constexpr or giving them exceptions specifications through type traits. Please look into that yourself.