Потому что это бессмысленно. Как и нельзя применить инкремент к объекту типа std::vector. Неважно, где выделена память -- важно, к какому объекту вы пытаетесь применить эту операцию.
В случае с массивами инкремент не имеет смысла, т.к. неясно, что должно произойти с самим массивом после этого (ведь инкремент -- операция, модифицирующая свой аргумент, в отличие от, например, оператора +).
Инкрементить можно итератор/указатель на какой-то элемент этого массива, чтобы получить итератор/указатель на следующий элемент.
Важно понимать, что массивы не являются указателями. Это принципиально разные сущности.
Массив содержит в себе все свои элементы и охватывает весь диапазон (нельзя заставить массив уже после создания начать охватывать только часть своего диапазона).
Указатель же только ссылается на память, принадлежащую кому-то другому (возможно, какому-нибудь массиву).
Хотя массивы и умеют неявно приводиться к указателям, и во многих случаях это делают автоматически.
Например, при применении оператора + к массиву.
Оператор + (в общем случае) не изменяет своих операндов, а создаёт новый объект, поэтому с ним такой неоднозначности не будет.
В выражении arr+1 (где arr -- массив) компилятор сначала как бы попытается применить оператор + к массиву и целому числу, у него не получится (т.к. к массиву самому по себе что-то прибавлять нельзя -- опять же, это бессмысленная/неоднозначная операция). Но затем он увидит, что у этого массива есть оператор неявной конвертации к чему-то, что можно использовать в таком контексте: указателю. И поэтому воспользуется данным приведением, сконвертирует arr к новому указателю, и применит +1 уже к этому указателю, в результате вернув указатель на следующий элемент.
Принципиальное отличие в том, что в данном примере сам массив никто не пытается модифицировать.
Вы можете спросить: почему тогда в случае с ++arr компилятор не провернёт ту же фишку, приведя массив к указателю и применив инкремент к этому указателю?
Фишка в том, что сам массив от этого не изменится (т.к. менялся бы только временный объект-указатель), и в результате вы бы не получили ничего. Вот совсем ничего. А это вряд ли то, что вы ожидаете. Потому что этот временный проинкрементированный указатель после завершения операции был бы тут же уничтожен -- на оригинальном массиве это бы никак не сказалось. Операция оказалась полностью бессмысленной.
Поэтому для встроенных типов такие операции над prvalue (временными безымянными объектами, не привязанными к переменной) запрещены. Здесь уже речь не идёт конкретно о массивах.
Это то же самое, что написать ++(1+2). Не скомпилится. Так как выражение (1+2) вернёт временный объект типа int, не привязанный ни к какой именованной переменной, и его инкрементировать попросту бессмысленно.
Так что если вы хотите использовать инкремент с массивом, предполагая, что эта операция должна осуществлять переход к следующему элементу -- просто создайте именованную переменную-указатель через описанное выше неявное приведение, и инкрементируйте уже этот указатель.
В таком случае всё будет в порядке, поскольку 1) данный указатель будет новым объектом, и его изменение само по себе никак не повлияет на сам массив; 2) инкремент указателя -- операция понятная и однозначная:
int arr[42];
//++arr; // error!
int* ptr = arr; // array-to-pointer decay
++ptr; // ok!
То же самое можно сказать и о динамических массивах, не являющихся указателями. В C++ их роль чаще всего играют экземпляры шаблона std::vector:
std::vector<int> arr(42);
//++arr; // error!
int* ptr = arr.data();
++ptr; // ok!