Почему строка, представленная суффиксом sv, не имеет срока действия? - PullRequest
1 голос
/ 18 мая 2019

Распространенной ошибкой является инициализация std::string_view временным std::string.

using namespace std::literals;

std::string_view sv1 = "foo" ; // good
std::string_view sv2 = "bar"s; // bad: "foo"s will expire

std::cout << sv1 << "\n"       // outputs foo
          << sv2 << "\n";      // undefined behavior

Это потому, что "bar"s, временный std::string, уничтожается в конце полное выражение .

Но как насчет "foo"sv?

std::string_view sv3 = "baz"sv;

Конечно, это должно работать, потому что суффикс sv в противном случае бесполезен.Но чем это принципиально отличается от "baz"s?Другими словами, почему строка, введенная "baz"sv, не имеет срока действия?

1 Ответ

6 голосов
/ 18 мая 2019

Почему декларация sv2 плохая

За [basic.string.literals] / 1 :

string operator""s(const char* str, size_t len);

Возвращает: string{str, len}.

В "foo"s строковый литерал "foo" используется для инициализации временного std::string.Символы копируются в базовый массив временного std::string.std::string_view - это не принадлежащий вид, а sv2 указывает на базовый массив временного std::string.После уничтожения временного std::string, sv2 продолжает указывать на базовый массив (срок действия которого истек), и попытка вывести sv2 приводит к неопределенному поведению.

Почему объявление sv3 хорошо

За [string.view.literals] / 1 :

constexpr string_view operator""sv(const char* str, size_t len) noexcept;

Возвращает: string_­view{str, len}.

Следовательно, объявление sv3 эквивалентно: 1

std::string_view sv3{"baz", 3};

sv3 непосредственно указывает на строковый литерал "baz".Строковый литерал имеет статическую длительность хранения и не имеет срока действия.

1 Здесь есть некоторая тонкость.Копия elision может или может не применяться здесь.Поскольку string_view s не являются владельцами, при копировании string_view s не появляются новые временные строки.Следовательно, независимо от того, должна ли быть сделана копия, состояние sv3 остается одним и тем же.

...