2016-10-17 1 views
0

Может кто-нибудь предложить способ иметь нульstd::ostringstream что избегает делать какие-либо работы по параметрам, передаваемым ему с <<?Реализация не-оп зЬй :: ostringstream, который может быть принят в качестве ссылки станд :: ostringstream

Есть два соответствующих сообщений здесь Implementing a no-op std::ostream и Printing to nowhere with ostream, до сих пор наиболее перспективным решением является https://stackoverflow.com/a/760353/826203, но в то время как тест он

int main() { 
    onullstream os; 
    os << 666; 

// std::ostringstream & oss = os; // error C2440: 'initializing' : cannot convert from 'onullstream' to 'std::ostringstream &' 
    oss << "hello, world"; 
} 

однако, это может быть использовано только как os<<666, но может не быть используется как std::ostringstream &. в любом случае?

+1

Вы получаете сообщение об ошибке, потому что 'станд :: ostringstream' и' onullstream' различные части дерево наследования. Хотя оба они наследуются от 'std :: ostream', они иначе не связаны. Вместо этого я считаю, что требование использовать 'std :: ostringstream' здесь является ложным требованием, что вам действительно не нужно. Например, если у вас есть функция, которую вы вызываете с потоком, вам понадобится ссылка 'std :: ostream'. Затем вы можете передать объект 'std :: ostringstream' * или * объект' onullstream'. –

ответ

3

Самый простой способ создать нерабочий поток - фактически не создавать пользовательский класс потока, а скорее отключать существующий поток. Например, вы можете отключить форматирование к std::ostream, установив поток буфер нуля:

std::ostringstream out; 
out.std::ostream::rdbuf(0); 
// any attempt to write anything to out will fail. 

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

struct nullbuf: std::streambuf { 
    std::streambuf::int_type overflow(std::streambuf::int_type c) { 
     return std::char_traits<char>::not_eof(c); 
    } 
}; 
// ... 
nullbuf   buf; 
std::ostringstream out; 
out.std::ostream::rdbuf(&buf); 

Обратите внимание, что я хотел бы также рекомендовать не иметь функции взять std::ostringstream в качестве аргументов. Вместо этого любая функция, которая не создает поток, должна перемещаться в терминах std::ostream&. Если существующие интерфейсы уже принимают std::ostringstream вы можете создать аа поток нулевой, выводя из std::ostringstream и настройки буфера потока соответственно:

class onullstream 
    : private virtual nullbuf 
    , public std::ostringstream { 
public: 
    nullstring() 
     : std::ios(this) 
     , std::ostringstgream() { 
     this->std::ostream::rdbuf(this); 
    } 
}; 
+0

спасибо! Могу ли я спросить 1) что вы подразумеваете под «фактическим форматированием будет выполнено», и 2) почему не рекомендуется брать «std :: ostringstream» в качестве аргументов, вместо этого принимать 'std :: ostream &'? – athos

+0

@athos: извините, я продолжаю забывать, что производные потоки имеют перегрузки для 'rdbuf()' (которые довольно ошибочны). Просто назовите вызов 'std :: ios'-версии функции, например:' out.std :: ostream :: rdbuf (& buf) '(аналогично для другой версии). –

+0

@athos: по вашим другим вопросам: 1. «nullbuf» просто ест всех отправленных им символов. Однако, поскольку он успешно, все персонажи создаются. То есть, когда вы вставляете, например, 'int',' int' будет преобразован в последовательность 'char', представляющую значение 'int', и' char 'не будет использоваться. То есть, существует потенциальная значительная работа, проделанная только для игнорирования символов! Недействительность потока довольно принудительно, то есть установка буфера потока на «0», заставляет операции потока не преобразовывать значение, но все операции завершаются с ошибкой. –

 Смежные вопросы

  • Нет связанных вопросов^_^