ideas
ideas copied to clipboard
Определить `template<size_t N> std::string_view::string_view(const char (&)[N]);`
C-массив можно инициализировать литералом или списком:
const char array1[] = "abcdefgh";
const char array2[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
Конструктор std::string_view неявно преобразует ссылку на C-массив в const char*.
Для array1 вызовется strlen (использовать N не будем, т.к. внутри литерала может быть \0).
array2 же не нуль-терминирован, и вызовет неопределённое поведение.
Поэтому предлагается определить более безопасный конструктор:
template<typename CharT>
template<size_t N>
constexpr std::basic_string_view<CharT>::basic_string_view(const CharT (& array)[N])
: basic_string_view(array, std::find(std::begin(array), std::end(array), CharT{}) - std::begin(array))
{ }
Текущее поведение меняется только там, где оно уже было неопределённым.
Если не делегировать конструкторы, а инициализировать поля, то можно добавить noexcept.
Мотивационный пример с UB: https://godbolt.org/z/exYY8G997
P. S. Для общности можно добавить template<typename CharT> std::char_traits<CharT>::length(const CharT* const, size_t max_length). Хотя там уже есть find…
Кому и как можно показать черновик предложения?