Как я могу стать владельцем данных std::string char без копирования и без сохранения исходного объекта std::string? (Я хочу использовать движущуюся семантику, но между разными типами.)
Я использую компилятор C++11 Clang и Boost.
В основном я хочу сделать что-то эквивалентное этому:
{
std::string s(“Possibly very long user string”);
const char* mine = s.c_str();
// 'mine' will be passed along,
pass(mine);
//Made-up call
s.release_data();
// 's' should not release data, but it should properly destroy itself otherwise.
}
Чтобы уточнить, мне нужно избавиться от std::string: в будущем. Код работает как со строковыми, так и с двоичными данными и должен обрабатывать их в одном и том же формате. И мне нужны данные из std::string, потому что они поступают из другого слоя кода, который работает с std::string.
Чтобы дать больше перспективы, когда я сталкиваюсь с желанием сделать это: например, у меня есть асинхронная оболочка сокета, которая должна иметь возможность принимать как std::string, так и двоичные данные от пользователя для записи. Обе версии записи «API» (принимая двоичные данные std::string или строки) внутренне разрешаются в одну и ту же (двоичную) запись. Мне нужно избегать копирования, так как строка может быть длинной.
WriteId write( std::unique_ptr< std::string > strToWrite )
{
// Convert std::string data to contiguous byte storage
// that will be further passed along to other
// functions (also with the moving semantics).
// strToWrite.c_str() would be a solution to my problem
// if I could tell strToWrite to simply give up its
// ownership. Is there a way?
unique_ptr<std::vector<char> > dataToWrite= ??
//
scheduleWrite( dataToWrite );
}
void scheduledWrite( std::unique_ptr< std::vecor<char> > data)
{
…
}
std::unique_ptr в этом примере, чтобы проиллюстрировать передачу права собственности: мне подходит любой другой подход с той же семантикой.
Меня интересуют решения для этого конкретного случая (с буфером std::string char) и такого рода проблемы со строками, потоками и подобными общими: советы по перемещению буферов между строками, потоками, стандартными контейнерами и типами буферов.
Я также был бы признателен за советы и ссылки с подходами к проектированию C++ и конкретными методами, когда речь идет о передаче данных буфера между различными API/типами без копирования. Я упоминаю, но не использую потоки, потому что я не уверен в этом вопросе.
std::unique_ptr<char[]>
было бы единственным, что допускает что-то подобное. - person ildjarn   schedule 03.07.2012std::unique_ptr<char[]>
вместоstd::string
для начала. - person ildjarn   schedule 03.07.2012std::string
отлично хранит двоичные данные (включая встроенные нули), верно? Вы уверены, что не можете просто продолжать использоватьstd::string
? - person ildjarn   schedule 03.07.2012std::string
содержит любойchar
, он не ограничен печатными символами. Если раньше у вас были проблемы, это было связано с тем, что вы использовалиstd::string::c_str()
-- при сохранении двоичных данных вы должны вместо этого использоватьstd::string::data()
. - person ildjarn   schedule 03.07.2012size()
илиlength()
- ни один из них не заботится о встроенных нулях (и использует cppreference, а не cplusplus .com, если вам нужна достоверная информация :-]). - person ildjarn   schedule 03.07.2012std::string
не завершается нулем и может содержать любые символы, включая нетекстовые символы и символы NUL, почему бы и нет просто мандатstd::string
? В любом случае, если вам это действительно нужно, ваш внутренний код может работать с точки зренияboost::variant<std::unique_ptr<char[]>, std::string>
(документов ), позволяя пользователю пройти любой из них и не теряя эффективности с вашей стороны (требуется только две реализации внутри посетителя). - person ildjarn   schedule 03.07.2012