cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

Определить `template<size_t N> std::string_view::string_view(const char (&)[N]);` #506

Open pavelkryukov opened 2 years ago

pavelkryukov commented 2 years ago

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

pavelkryukov commented 2 years ago

Кому и как можно показать черновик предложения?