Преобразование std::stringstream в const char** без выделения памяти

Насколько я понимаю, std::stringstream внутренне представлен не как std::string, а скорее как набор экземпляров std::string. (поправьте меня, если я ошибаюсь).

У меня есть данные, представленные как std::stringstream, и я хочу передать их функции C (clCreateProgramWithSource из OpenCL), которая ожидает данные в виде массива массивов символов. (const char**).

Есть ли способ сделать это без предварительного создания одной строки, содержащей все содержимое потока строк, например, следующим образом:

std::string tmp1 = my_stringstream.str();
const char* tmp2 = tmp1.c_str();
const char** tmp3 = &tmp2;

ИЗМЕНИТЬ

Дополнительный вопрос:

Если это не возможно, есть ли альтернатива std::stringstream, унаследованная от std::ostream, которая разрешает этот низкоуровневый доступ?


person Joel    schedule 19.01.2013    source источник
comment
Реализация stringstream не указана. Для C++ внутренний объект streambuf был бы полезной низкоуровневой точкой доступа, но для взаимодействия C ваш код в основном настолько хорош, насколько это возможно.   -  person Kerrek SB    schedule 19.01.2013
comment
@KerrekSB Хорошо, я думал, что должен быть какой-то способ обойти это, что, по крайней мере, сработает для стандартной реализации stringstream. С откатом к приведенному выше коду в других случаях.   -  person Joel    schedule 19.01.2013
comment
В качестве запасного варианта вы можете использовать ostream или streambuf для реализации собственного потока, если объединение и разделение потока на самом деле является узким местом. (stackoverflow.com/questions/6490499/)   -  person Lol4t0    schedule 19.01.2013
comment
Вы пытаетесь оптимизировать на совершенно неправильном уровне. Копирование строки стоит буквально ничего по сравнению с тем, что делает clCreateProgramWithSource. Это как снять муху со слона и надеяться, что он похудеет.   -  person Bo Persson    schedule 19.01.2013
comment
@ Lol4t0 Спасибо за подсказку о том, как реализовать поток. Я рассмотрю это, если это действительно окажется узким местом, как вы правильно заметили.   -  person Joel    schedule 19.01.2013
comment
@BoPersson Я на 100% уверен, что вы правы в том, что накладные расходы в clCreateProgramWithSource. На самом деле, я протестировал создание промежуточного кода LLVM напрямую вместо генерации и компиляции кода с помощью Clang, только чтобы понять, что разницы в производительности практически нет. И моя реализация OpenCL использует Clang/LLVM afaik. Но меня все еще интересует преобразование std::stringstream в char** для взаимодействия C++/C в целом.   -  person Joel    schedule 19.01.2013
comment
Не уверен, насколько это правильно, но я сделал так: stream.str().c_str()   -  person Tomáš Zato - Reinstate Monica    schedule 18.03.2013


Ответы (1)


Получив streambuf строкового потока, мы можем явно установить буфер, который он должен использовать:

#include <sstream>

constexpr size_t buffer_size = 512;

void dummy_clCreateProgramWithSource(const char **strings) {}

int main () {
  char * ss_buffer = new char[buffer_size];
  std::stringstream filestr; // TODO initialize from file
  filestr.rdbuf()->pubsetbuf(ss_buffer,buffer_size);
  const char** extra_indirection = const_cast<const char **>(&ss_buffer);
  dummy_clCreateProgramWithSource(extra_indirection);
  return 0;
}

Обратите внимание на const_cast, который сообщает, что может быть ложью; мы обещаем OpenCL, что не будем писать в stringstream после вызова clCreateProgramWithSource.

person TamaMcGlinn    schedule 26.06.2020