Допустимо ли создание итератора для end(str)+1 для std::string? 
И если это не так, почему бы вам не сделать это?
Этот вопрос ограничен С++ 11 и более поздними версиями, поскольку в то время как pre-С++ 11 данные уже были сохранены в непрерывном блоке в любых, но редких игрушках-играх POC, данные не нужно было хранить таким образом. 
И я думаю, что это может иметь значение.
Значительное различие между std::string и любым другим стандартным контейнером, о котором я размышляю, состоит в том, что он всегда содержит один элемент больше, чем его size, нулевой ограничитель, для выполнения требований .c_str().
21.4.7.1 basic_string accessors [string.accessors]
const charT* c_str() const noexcept; const charT* data() const noexcept;1 Возвращает: указатель
pтакой, чтоp + i == &operator[](i)для каждогоiв[0,size()].
2 Сложность: Постоянное время.
3 Требуется: программа не должна изменять любые значения, хранящиеся в массиве символов.
Тем не менее, хотя это должно гарантировать, что указанное выражение действительно, для согласованности и взаимодействия с нулевыми строками, если ничего другого, единственный найденный мной параграф вызывает у него сомнение:
21.4.1 Общие требования basic_string [string.require]
4 Объекты char в объекте
basic_stringдолжны храниться смежно. То есть для любогоbasic_stringобъектаsидентификатор&*(s.begin() + n) == &*s.begin() + nбудет выполняться для всех значенийnтаких, что0 <= n < s.size().
(Все цитаты из окончательного варианта С++ 14 (n3936).)
Связано: Право на перезаписывание нулевого терминатора std::string?
