Как я могу заменить член std::string на строку ограниченного размера без кучи?

У меня есть кодовая база с повсеместной структурой данных; и указанная структура имеет член std :: string. Теперь по причинам я хочу, чтобы эта кодовая база работала, когда std :: string недоступен, и фактически без динамического выделения памяти (по крайней мере, не обычным способом). Я также могу проверить, что этот строковый член никогда не имеет строки длиннее M символов (а M мало).

Теперь, чем мне заменить std :: string, чтобы мне не пришлось много переписывать, с одной стороны; и что мои ограничения удовлетворены другим?

Примечание:

  • Я не могу переместить вычисление строки во время компиляции.
  • Ничего страшного, если в решении есть только тривиальный конструктор, const char* конструктор или и то, и другое.
  • Решения с использованием std::string_view может быть актуальным (но я не уверен, будет ли это полезно).

2 ответа

вероятно, будет достойным и простым вариантом для исследования. Объем перезаписи может быть больше или меньше в зависимости от того, как вы использовали строковый член до сих пор.

Если "std ::stringiness" члена используется часто, то вы могли бы уменьшить количество перезаписи, реализовав собственный класс, который предлагает аналогичный интерфейс, но внутренне использует char[M + 1]. boost::static_stringупомянутый Дрю Дорманн является шаблоном для такого класса.

PS Если вы все еще можете использовать динамическую память и ограничены в ее использовании, то вы потенциально можете продолжать использовать std::stringвместо этого с настраиваемым распределителем, как упоминал Галик .

Потенциальное решение с минимальными хлопотами могло бы использовать особенности вашего случая, жертвуя общностью ради простоты:

Вы написали, что строка, которую хотите заменить, на самом деле является членом другой структуры. Это уже позволяет использовать член массива структуры, как предлагает @eerorika, не беспокоясь о распаде массива. Но - массивы не являются интерфейсом std :: string.

Вы сказали, что не видели, как std::string_view было бы полезно - и это потому, что для него нет места для хранения.

Что ж, объедините два! ... нет, не пишите новый класс с хранилищем и строковым интерфейсом. Скорее добавьте char [M+1] field в вашу структуру с новым именем поля и используйте исходное имя поля для string_view, смотрящего на массив (с соответствующей длиной, конечно)!

Это немного усложняет конструирование и присваивание - то есть это больше не тривиальная поэлементная конструкция - но тогда вы сможете передавать этот объект и использовать то же поле, что и раньше, например std ::string.

        struct ubiquitous {
     // other members
     char[M+1] string_data;
     std::string_view original_field;

     // apply rule of 5: ctor, move ctor, assignment, move assignment
     // and a trivial dtor (at least for your two fields)
     // ... so, a "rule of 4" in this case
  };

Если у вас нет string_viewдоступный, то есть это код до C++17, тогда вы можете получить перенесенный обратно string_view Мартина Моэна (GitHub).

Другие вопросы по тегам