Existe-t-il une implémentation de null std::ostream dans C++ ou les bibliothèques?
4 réponses
si vous avez boost, alors il y a une implémentation nulle ostream & istream disponible dans boost/iostream/device/null.hpp . L'essentiel:
#include "boost/iostreams/stream.hpp"
#include "boost/iostreams/device/null.hpp"
...
boost::iostreams::stream< boost::iostreams::null_sink > nullOstream( ( boost::iostreams::null_sink() ) );
...
la solution la plus simple est simplement d'utiliser un std::ofstream
non ouvert . Ce
entraînera dans un état d'erreur dans le flux, mais la plupart des outputters ne
vérifiez ceci; l'idiome habituel est de laisser le chèque à la fin, après le
(ce qui le mettrait dans le code que vous avez écrit, où vous savez que le
flux doit être valide).
sinon, c'est assez simple à mettre en œuvre: il suffit de créer un
streambuf
qui contient un petit tampon, et le met en place dans overflow
(toujours de retour succès). Notez que ce sera plus lent que l'
le fichier non ouvert, cependant; les divers opérateurs >>
seront encore à tous les
la conversion (ce qu'ils ne font pas si le flux a un État d'erreur).
EDIT:
class NulStreambuf : public std::streambuf
{
char dummyBuffer[ 64 ];
protected:
virtual int overflow( int c )
{
setp( dummyBuffer, dummyBuffer + sizeof( dummyBuffer ) );
return (c == traits_type::eof()) ? '"151900920"' : c;
}
};
il est habituel de fournir une classe de commodité dérivée de istream
ou ostream
ainsi, qui contiendra une instance de ce
tampon qu'il utilise. Quelque chose du genre:
class NulOStream : private NulStreambuf, public std::ostream
{
public:
NulOStream() : std::ostream( this ) {}
NulStreambuf* rdbuf() const { return this; }
};
Ou vous pouvez simplement utiliser un std::ostream
, en passant l'adresse de
le streambuf.
si vous définissez badbit
sur un flux, il ne produira rien:
#include <iostream>
int main() {
std::cout << "a\n";
std::cout.setstate(std::ios_base::badbit);
std::cout << "b\n";
std::cout.clear();
std::cout << "c\n";
}
sorties:
a
c
je sais que c'est un fil très ancien, mais je voudrais ajouter ceci à quiconque est à la recherche de la même solution sans boost et et le plus rapide.
j'ai combiné trois propositions différentes ci-dessus et une en écrivant directement à /dev/null (donc cela implique le noyau.)
étonnamment, le NullStream qui a obtenu le plus de votes a réalisé le pire.
Voici les résultats pour 100,000,000 écrit:
a) /dev/null : 30 seconds
b) NullStream: 50 seconds
c) badbit : 16 seconds (the winner in speed, but cannot test for errors!)
d) boost : 25 seconds (the ultimate winner)
voici le code d'essai
#include <iostream>
#include <fstream>
#include <time.h>
#include <boost/iostreams/stream.hpp>
class NullStream : public std::ostream {
class NullBuffer : public std::streambuf {
public:
int overflow( int c ) { return c; }
} m_nb;
public:
NullStream() : std::ostream( &m_nb ) {}
};
int test( std::ostream& ofs, const char* who ) {
const time_t t = time(NULL);
for ( int i = 0 ; i < 1000000000 ; i++ )
ofs << "Say the same" ;
std::cout << who << ": " << time(NULL) - t << std::endl;
}
void devnull() {
std::ofstream ofs;
ofs.open( "/dev/null", std::ofstream::out | std::ofstream::app );
test(ofs, __FUNCTION__);
ofs.close();
}
void nullstream() {
NullStream ofs;
test(ofs, __FUNCTION__);
}
void badbit() {
std::ofstream ofs;
ofs.setstate(std::ios_base::badbit);
test(ofs, __FUNCTION__);
}
void boostnull() {
boost::iostreams::stream< boost::iostreams::null_sink > nullOstream( ( boost::iostreams::null_sink() ) );
test(nullOstream, __FUNCTION__);
}
int main() {
devnull();
nullstream();
badbit();
boostnull();
return 0;
}
MODIFIER
la solution la plus rapide - où nous utilisons badbit - présente un inconvénient. Si le programme vérifie si la sortie est correctement écrit - et je n'ai aucune idée pourquoi le programme ne devrait pas le faire - il échouera à cause de cette badbit. Par conséquent, le second - boost - est le gagnant.