Simple raw buffer queue implementation
You are not allocating per se when when writing to the queue. std::array is backed by a plain C-array on the stack, that gets moved. 

So you only ever allocate depending on the underlying container the std::queue is based on. By default this is a std::deque.

I do not really understand the need for the std::array in the type though. Why not just use a std::string and limit the size of it to 4096? There is even a constructor that does explicitely that string (const char* s, size_t n)

Before I get to the Code there are some other things I would like to mention:


why are you not useing std::copy instead of memcpy. The former works better with C++ and will in the end almost always end up as memcpy?
You do not need to define the special member functions. In fact you have forgotten 2 of then, aka copy assignment and copy constructor. Why do I say forgotten? Because there is no way to tell. So If you want your queue to be move only then you should actually delete those special member functions you dont want.
In your read function you never check whether the size you want to read is actually valid. Is that intendend? If so why? A std::array is not initialized so the memory in it that is not written by you will be random. You are not writing to it but you are copying it around. So you should actually take the minimum out of size and queue.front().size()
std::string has a member function std::string::copy that copyies a certain amount of chars to a buffer (http://www.cplusplus.com/reference/string/string/copy/). I would suggest to use that for writing back to the buffer 


That leads me to the following:

#include &lt;string&gt;
#include &lt;queue&gt;
#include &lt;vector&gt;

class simple_queue
{
private:
    static constexpr uint32_t max_msg_size = 4096;
    std::queue&lt;std::string, std::vector&lt;std::string&gt;&gt; char_queue;

public:  
   simple_queue(const simple_queue&amp;) = delete;
   simple_queue&amp; operator=(const simple_queue&amp;) = delete;

    uint32_t write(const char* const buff, const uint32_t size) noexcept
    {
        const uint32_t size_to_copy = std::min(max_msg_size, size);
        char_queue.emplace(buff, size_to_copy);
        return size_to_copy;
    }

    uint32_t read(char* const buff, const uint32_t size) noexcept
    {
        if (char_queue.empty())
        {
            return 0;
        }
        std::string&amp; msg = char_queue.front();
        const uint32_t size_to_copy = std::min(msg, size);
        msg.copy(buff, size_to_copy, 0);

        char_queue.pop();
        return size_to_copy;
    }
};


EDIT:

I forgot to mention, that now you should use a std::vector as backing of the queue as your are not storing a gargantuan array but rather a mall std::string. 

Note that it actually ends up being the same. The std::deque based std::array implementation is backed by a linked list, so each array ends up in a node of a linked list, which is kind of similar to the separate allocation of the std::string