ideas icon indicating copy to clipboard operation
ideas copied to clipboard

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

Open pavelkryukov opened this issue 3 years ago • 1 comments

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 avatar Jan 29 '22 14:01 pavelkryukov

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

pavelkryukov avatar Feb 05 '22 11:02 pavelkryukov