Странное поведение stringstream передается по ссылке - PullRequest
0 голосов
/ 12 марта 2012

Для проекта я бы хотел использовать stringstream для передачи данных.Чтобы достичь этой цели, я должен передать некоторый строковый поток в качестве параметра некоторой функции, но когда я выводю строковые потоки, я вижу что-то вроде адреса.

Код:

#include <iostream>
#include <sstream>

void doStuff(const std::iostream& msg)
{
    std::cerr << msg << std::endl;
}

int main(void)
{
    doStuff(std::stringstream("av"));
}

вывод: 0xbff4eb40

Может кто-нибудь объяснить, почему я получаю адрес при передаче значения r?

И почему я не могу передать поток строк по значению?

Ответы [ 2 ]

4 голосов
/ 12 марта 2012

Возможно, вы хотите получить доступ к строке, в которой поток строк хранит свои данные:

void doStuff(const std::stringstream& msg)
{
    std::cerr << msg.str() << std::endl;
}

В вашем коде происходит следующее: iostreams содержит void* operator, который возвращает 0, если поток содержит какую-либо ошибку или достиг EOF, и другое значение в противном случае. Это полезно для проверки ошибок.

Когда вы пытаетесь записать ваш поток в std::cerr, компилятор понимает, что поток может быть преобразован в void *, используя этот оператор, и что void * может быть записан в ostream (оператор << был определяется), и, следовательно, использует его. </p>

Обратите внимание, что я изменил сигнатуру метода, чтобы он получал std :: stringstream в качестве аргумента, поскольку std :: iostream :: str не определен (этот метод доступен только для потоков строк).

1 голос
/ 12 марта 2012

Вы получаете адрес, потому что он (как и другие потоки) имеет преобразование в void * (что в первую очередь полезно как логическое значение, чтобы увидеть, не удалось ли прочитать / записать поток).

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

Чтобы напечатать содержимое потока, вы можете сделать что-то вроде:

void dostuff(std::iostream &msg) { 
    std::cerr << msg.rdbuf() << "\n";
}

Редактировать: Вот полная демонстрационная программа:

#include <iostream>
#include <sstream>

void show(std::ostream &os) { 
    std::cout << os.rdbuf() << "\n";
}


int main(){ 
    std::stringstream test("whatever");
    show(test);
    return 0;
}

Когда я ее выполняю, вывод, который я получаю, является ожидаемым "что угодно".

...