Преимущества вектора <char> по строке?

Этот вопрос связан, но не совсем так, как этот вопрос.

Есть ли какие-либо преимущества при использовании std::vector<char> вместо std::string для хранения произвольных двоичных данных в сторону из проблем, связанных с читабельностью?

то есть. Есть ли какие-либо задачи, которые проще/эффективнее/лучше выполнять вектор с по сравнению со строкой?

Ответ 2

Помимо читаемости (которую нельзя недооценивать), я могу вспомнить пару незначительных проблем с производительностью/памятью с использованием std::string over std::vector:

  • В некоторых современных реализациях std::string используется небольшая оптимизация строк. Если вы храните данные, превышающие внутренний буфер string, он становится пессимизацией, снижая эффективность копирования, перемещения и swap 1 и увеличивая sizeof() без выгоды.

  • Эффективная реализация std::string всегда будет выделять как минимум еще 1 байт, чем текущий размер для хранения завершающего нуля (для этого не требуется дополнительная логика в operator[], чтобы справиться с str[size()]).

Я должен подчеркнуть, что оба эти вопроса очень незначительны; стоимость их работы, скорее всего, будет потеряна при фоновом шуме. Но вы спросили.


1 Эти операции требуют разветвления на size(), если используется оптимизация небольших строк, тогда как они не имеют хорошей реализации std::vector.

Ответ 3

Помимо читаемости и обеспечения того, что другой сопровождающий не путает цель std::string, в функции не так много разницы. Разумеется, вы можете рассмотреть char */malloc, если эффективность является единственным соображением.

Одна потенциальная проблема, о которой я могу думать:

std::string по умолчанию сохраняется <char>. Если позже вам понадобится обращаться с другим типом (например, без знака), вам может понадобиться:

  • Создайте свой собственный typedef std::basic_string<unsigned short> (который отводит вас от нормальной обработки std::string)
  • Предварительно примените некоторую логику reinterpret_cast в сеттере.

С помощью вектора вы можете просто изменить контейнер на std::vector<unsigned short>.

Ответ 4

Я думаю, что единственное преимущество, которое вы могли бы выиграть от этого, - это простота приращения над символами std::vector, но даже это можно сделать с помощью std::string.

Вы должны помнить, что даже если std::string похоже на объект, к нему можно получить доступ, как к массиву, поэтому даже доступ к определенным частям строки может быть выполнен без использования std::vector

Ответ 5

В идеале можно было бы использовать vector<unsigned char> для хранения произвольных двоичных данных, но я думаю, вы уже это знали, поскольку вы ссылались на старый вопрос.

Кроме того, использование вектора определенно будет более эффективным с точки зрения памяти, поскольку строка добавит завершающий символ Nul. Производительность также может улучшиться по мере того, как механизм распределения отличается для обоих - векторы гарантируют непрерывную память!

Кроме того, использование строки неверно, поскольку вызывающие/пользователи могут непреднамеренно ссылаться на некоторые из строковых методов, что может быть катастрофой.

Ответ 6

Как отмечают другие ответы, вектор может быть несколько быстрее, поскольку он гарантирует непрерывную память даже для небольших размеров и не добавляет в конец лишний нулевой байт. Тем не менее, гораздо проще (с точки зрения кода) объединить две строки, чем объединить два вектора:

Используя vector:

vector<char> a, b;
// ...
vector<char> c;
c.insert(c.end(), a.begin(), a.end());
c.insert(c.end(), b.begin(), b.end());

Используя string:

string a, b;
// ...
string c = a + b;