Как обнаружить использование оптимизации коротких строк std::string? В качестве вопросаC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как обнаружить использование оптимизации коротких строк std::string? В качестве вопроса

Сообщение Anonymous »

Изначально я задал такой вопрос:
Если у вас длинная строка:

Код: Выделить всё

std::string data("This is a string long enough so that it is not a short string");
Тогда вы увидите эту строку:

Код: Выделить всё

std::string_view dataView(std::begin(data) + 5, std::end(data) - 5);
Если я перенесу исходную строку:

Код: Выделить всё

std::string movedData(std::move(data));
Тогда я ожидаю, что представление dataView останется действительным.
Но это предположение не выполняется, если оптимизация коротких строк std::string вступит в силу, поскольку базовая память строки не выделяется динамически, и перемещение теперь (под капотом) становится разрушительной операцией копирования, оставляя представление недействительным.
Вопросы:
  • Есть ли что-то в стандарт об этом?
  • Есть ли способ обнаружить оптимизацию коротких строк (чтобы я мог предпринять соответствующие действия в конструкторе перемещения класса)?
Разъяснение/контекст
У меня есть класс, который хранит URL-адрес в виде строки, а затем доступ к каждой части URL-адреса сохраняется как представления исходного URL-адреса. Конечно, подсчет просмотров имеет свои затраты, но лучше рассчитывать их один раз, чем при каждом доступе (или это был мой мыслительный процесс). Для копии вы пересчитали представления, но при перемещении (как я думал) не требуется пересчитывать представления, так как базовое хранилище будет перемещено, и, следовательно, представления останутся действительными.

Код: Выделить всё

 class URL
{
std::string      url;
std::string_view schema;
std::string_view host;
std::string_view path;
// .. etc (for the multiple parts of a URL you can extract).
// Note: Parsing a URL correctly is non-trivial (handling IPV6, etc.).
//       Si I don't want to do it that often.

public:
// Default constructor.
URL() {}
// Normal constructor: Accept input by copy/move
URL(std::string urlInput)
: url(std::move(urlInput))
{
// Compute Views.
}
// Copy constructor.
URL(URL const& copy)
: url(copy.url)
{
// Compute Views.
}
// Move constructor
// I hoped I could simply swap the two objects.
// This works if there is no short string optimization.
URL(URL&& move) noexcept
{
swap(move);
}
// Assignment (both copy and move in one place).
// Use standard copy and swap idium.
URL operator=(URL assign) noexcept
{
swap(assign);
return *this;
}
// Faithful swap function.
void swap(URL& other) noexcept
{
using std::swap;
swap(url, other.url);
swap(schema, other.schema);
swap(host,   other.host);
swap(path,   other.path);
}

// Getter functions removed. But simply return std::string_view.
};
Вопросы/комментарии:

  • "... Тогда я ожидаю, что представление dataView останется действительным..."_ нет, после перемещения все указатели, ссылки и итераторы при перемещении из контейнера недействительны. Для системы единого входа исключений нет.
Представления должны были переместиться вместе с базовыми данными. Но SSO все портит. Поскольку это нарушает принцип наименьшего неожиданности, я думаю, комитет по стандартам подумает об этом и внесет что-нибудь в стандарт. Я надеялся, что кто-нибудь знает, есть ли что-нибудь в стандарте; в противном случае да, это будет UB.

  • На любом языке ничего не предполагайте, просто прочитайте документацию, там все есть std::string_view. Также известен как RTFM на инженерном языке ;)
К сожалению, en.cppreference.com не является авторитетным источником. Я надеялся, что кто-нибудь укажет мне правильное место в стандарте. Я могу прочитать это сам, я просто надеялся, что это может быть быстрее.

  • Если вы хотите, чтобы такое поведение сохранялось, вы можете вместо этого использовать std::vector и span. Вектору не разрешена оптимизация малых векторов.
Это кажется достойной альтернативой этой проблеме.

Подробнее здесь: https://stackoverflow.com/questions/798 ... a-question
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»