Подтвердить что ты не робот

Преобразование из std :: string_view в std :: string неявно. Что, черт возьми, подумал коммит?

Серьезно, что случилось. Существует неявное преобразование из std::string в std::string_view и это не считается небезопасным. Несмотря на то, что это, безусловно, может вызвать множество оборванных ссылок, если программист не проявляет осторожности.

С другой стороны, они отклонили неявное преобразование из std::string_view в std::string используя тот же аргумент, но совершенно противоположным образом: потому что программист может быть не осторожен.

Прекрасно, что они создали замену необработанного указателя const char*, делая его очень запутанным и лишенным кости:

  • Неявный const char*std::string: OK
  • Неявный std::string_viewstd::string: NOPE
  • Назначение std::string= const char*: OK
  • Назначение std::string= std::string_view: OK
  • Добавление std::string + = const char*: OK
  • Добавление std::string + = std::string_view: OK
  • Конкатенация const char* + std::string: OK
  • Конкатенация std::string_view + std::string: NOPE
  • Конкатенация std::string + const char*: OK
  • Concatenation std::string + std::string_view: NOPE

Я что-то пропустил или это полная чепуха?

В конце концов, насколько полезен этот строковый просмотр без всех важнейших частей, которые делают его похожим на const char*? Какой смысл интегрировать его в экосистему stdlib, не делая последнего шага, чтобы сделать его полным? В конце концов, если нам просто нужен объект, представляющий часть строки, которую мы могли бы написать самостоятельно. На самом деле, много библиотек уже много лет назад. Весь смысл сделать что-то стандартное - сделать его полезным для самых разных вариантов использования, не так ли?

Они собираются исправить это на С++ 2a?

4b9b3361

Ответ 1

Проблема заключается в том, что std::string_viewstd::string делает копию базовой памяти с полным распределением кучи, тогда как неявная std::stringstd::string_view нет. Если вы, в первую очередь, потрудились использовать std::string_view то вам, очевидно, нужны копии, поэтому вы не хотите, чтобы это происходило неявно.

Рассмотрим этот пример:

void foo1(const std::string& x)
{
    foo2(x);
}
void foo2(std::string_view x)
{
    foo3(x);
}
void foo3(const std::string& x)
{
    // Use x...
}

Функция foo2 могла бы использовать параметр const std::string&, но использовала std::string_view чтобы она была более эффективной, если вы передаете строку, которая не является std::string; никаких сюрпризов нет. Но он менее эффективен, чем если бы вы просто дали ему const std::string& parameter!

  • Когда foo2 вызывается с аргументом std::string (например, foo1): Когда foo2 вызывает foo3, он создает копию строки. Если у него был const std::string& argument, он мог бы использовать объект, который у него уже был.
  • Когда foo2 вызывается с аргументом const char*: скопируйте std::string раньше или позже; с параметром const std::string& он получает ранее, но в целом там ровно одна копия в любом случае.

Теперь представьте, что foo2 вызывает несколько функций, таких как foo3, или вызывает foo3 в цикле; он делает один и тот же объект std::string снова и снова. Вы хотите, чтобы компилятор уведомил вас об этом.