Мотивация:
Я использую некоторую библиотеку (которую я не контролирую) со следующей функцией:
char* foo(/*some parameters here */);
Который возвращает очень длинную строку с нулевым символом в конце. Теперь я хочу использовать функцию
void bar(const std::string& s);
которая доступна в другой библиотеке, которую я использую (то есть я не контролирую подписи ни одной из этих функций). Я хочу передать результат foo()
в bar()
— без копирования.
Вопрос:
Я хочу обернуть непрерывный буфер символов строковым объектом, чтобы его можно было передать как const std::string&
, Как я могу это сделать?
Заметки:
std::string
не вариант, так как у него нет соответствующих виртуальных методов. Это в основном оставляет нас с предположениями о реализации (или написанием разного кода для разных реализаций) и «ручного конструирования» std::string
пример. Таким образом, вопрос, кажется, о том, чтобы сделать это.Нет, ты не можешь. Просмотрите ваши требования и устраните необходимость в этом.
Вы можете эмулировать это используя boost::string_ref
,
Он имеет интерфейс, который совместим с std :: string:
boost::string_ref s = "hello world";
std::string compareto = "bye world";bool test = (compareto != s);
Конечно, это будет работать, только если вы можете принять string_ref
вместо string
в ваших интерфейсах. Таким образом, вы можете просто передать c-strings или std :: strings на досуге, и это будет правильно.
Старый вопрос, но с C ++ 17 у вас теперь есть станд :: string_view, который является точно подходящим инструментом для работы.
Просто инициализируйте это как:
auto my_string_view = std::string_view(foo(whatever));
…и использовать его везде, где вы бы использовали std::string const
, Или, если вам нужно сделать неконстантную копию, вы можете просто инициализировать временную строку из нее с помощью:
auto my_new_string = std::string{my_string_view}
Вы не можете сделать это, но вы можете легко написать свой собственный класс строки. Поскольку вы явно запрещаете делать какие-либо копии, вам даже не нужно поддерживать многие операции типа std :: string, такие как конкатенация и т. Д.
(Теоретически, вы можете поддерживать конкатенацию без копирования, создав внутреннее дерево буферов, но это было бы больше работы.)