Why pass input/output stream in a function? - c++

Why would we want to do this:
#include <iostream>
void print(std::ostream& os) {
os << "Hi";
}
int main() {
print(std::cout);
return 0;
}
instead of this:
#include <iostream>
void print() {
std::cout << "Hi";
}
int main() {
print();
return 0;
}
Is there some certain advantage or functionality that is obtained only with the first version?

Yes, the first version is significantly better. Like already mentioned in the comments, it allows you to use any kind of std::ostream, not just std::cout. Some of the most important consequences of this architectural choice are:
You can use your function to print the required data to standard output, a file, a custom class written by your colleagues (e.g. database adapter, logger).
It is possible to test your void print function. E.g.:
TEST(MyFunctionShould, printHello)
{
std::string expectedResult("Hello");
std::ostringstream oss;
print(oss);
ASSERT_EQ(expectedResult, oss.str());
}

Related

Storing a vector of various void function pointers with its parameters

I'm looking for a way to store function pointers in a container like a vector. This is possible if all the functions have the same parameters but can I do if the functions have individually unique parameters?
#include <iostream>
#include <vector>
using namespace std;
void sayHi() {
cout << "Hi" << endl;
}
void sayNum(int num) {
cout << num << endl;
}
int main() {
vector<void(*)()> funcs; // vector of 0 argument functions
funcs.push_back(sayHi);
funcs.push_back(sayNum); // can't store sayNum because it takes arguments
}
Note that I can't use std::function or std::bind because VS2013 doesn't have them and I'd rather not use the boost library. The solution must be allow the possibility to iterate through the vector of function pointers and execute each one with some valid arguments.
Forgive my potential ignorance about how function pointers work, I'm very used to doing this sort of thing in Javascript in one statement :P
Made the mistake of not including as I couldn't see it mentioned in anybody's code examples but it's probably just me being bad at C++.
Not going to accept my own answer, but thought I'd post my code just in the interests of anybody who might find it useful.
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
typedef std::vector<std::function<void(void)>> f_list;
f_list f1;
void _sayHi();
void _sayNum(int num);
void sayHi() {
f1.push_back(
std::bind(&_sayHi)
);
}
void sayNum(int num) {
f1.push_back(
std::bind(&_sayNum, num)
);
}
void _sayHi() {
cout << "hi" << endl;
}
void _sayNum(int num) {
cout << num << endl;
}
int main() {
sayHi();
sayNum(5);
for (int i = 0; i < f1.size(); i++) {
f1.at(i)(); // will execute desired functions
}
}
VS 2103 has std::function, std::bind and lambdas. Simply use them.

c++: Storing ostream in a List

I have a function
foo(ostream& os)
which writes to the ostream passed to it.
I now want to write a test and therefore would like to store whatever is written by foo into a list.
What is a clean way of doing this?
Populate the list with a std::ostringstream instance:
#include <sstream>
#include <cassert>
void foo(std::ostream& out) { out << "test1"; } // example implementation
void test_foo()
{
std::ostringstream buffer;
foo(buffer);
assert(buffer.str() == "test1");
}

Make a wrapper for cout?

So here's an interesting question, How would I make something kinda like a wrapper for cout?
I want to be able to add it into a dll so I can throw it into my programs. but the basic syntax of it should be
Mything::mesage << "I'm some text" << im_an_int << someclass << mything::endl;
or
Mything::mesageandlog << "I'm going to print to console, and to a file!" << mything::endl;
I can handle most of the internal logic but as to what I should put to even do this. kinda stumped.
Possibly make a static stream member in my class called message, then have an event fire when its written too that runs it through a method?
Idk, I looked around and found something sortA similar, but as for throwing it into a dll I'm at a loss. (How to write a function wrapper for cout that allows for expressive syntax?)
because this requires me to use extern and a variable, but how would I make it static so I can just straight call it without creating a variable?
Bit of clarification, something like this:
mydll.h
#include <iostream>
namespace mynamespace {
extern struct LogMessage{};
template <typename T>
LogMessage& operator<< (LogMessage &s, const T &x) {
SetStdHandle(STD_OUTPUT_HANDLE, GetStdHandle(STD_OUTPUT_HANDLE));
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE);
std::cout << "[IF] ";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_WHITE);
//LogTimestamp(); --ill impliment this.
std::cout << x << endl;
//writeStreamToLogfile(s); --and ill handle this.
return s;
}
}
driverprogram.h
#include <mydll.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
mynamespace::LogMessage << "Something: << std::endl;
}
expected output:
"[IF] [00:00:00] Something
You can create a struct, that has a << operator
struct OutputThing
{
template< class T >
OutputThing &operator<<( T val )
{
std::cout<<val;
return *this;
}
};
Now whenever you want to log, you will have to instance the object.
OutputThing()<<"x ="<<x;
If you want to avoid the repeated construction and destruction of the object, you can make it a singleton.
struct OutputThingSingleton
{
static OutputThingSingleton& GetThing()
{
static OutputThingSingleton OutputThing;
return OutputThing;
}
template< class T >
OutputThingSingleton &operator<<( T val )
{
std::cout<<val;
return *this;
}
private:
OutputThingSingleton()
{};
};
So the call now looks like
OutputThingSingleton::GetThing()<<"x ="<<x;
Which you could shorten using a macro.
This will work across multiple dlls, however depending on how it is used you can have multiple instances of the singleton existing. This would work fine as long as you don't want to maintain any state in your singleton. If you do need to ensure a single instance, you can compile it in its own dll. Any other binary that uses this dll will share the single instance 'owned' by the dll.
First of all, just to give fair warning, I'm pretty sure this won't work in a DLL. You want to put it into a header (as it's shown here).
Second, it's probably a little more elaborate than you were considering. In particular, it defines a multi-output stream class that works like any other stream. Essentially any normal overload of operator<< should work fine with it.
Unlike a normal stream operator, however, the output goes to multiple streams, and each line of output (on all the streams) is preceded by a prefix (currently set to the value "[FIX]", but it just uses the content of a string, so whatever you put in that string should work. A more polished/finished implementation would probably allow you to set the prefix with something like a manipulator, but this (currently) doesn't support that.
Finally, it does some variadic template trickery, so you can specify the output files as either file names or existing ostream objects, or a combination thereof (e.g., see demo main at end).
First, the header:
#ifndef LOGGER_H_INC_
#define LOGGER_H_INC_
#include <iostream>
#include <streambuf>
#include <vector>
#include <fstream>
class logger: public std::streambuf {
public:
logger(std::streambuf* s): sbuf(s) {}
~logger() { overflow('\n'); }
private:
typedef std::basic_string<char_type> string;
int_type overflow(int_type c) {
if (traits_type::eq_int_type(traits_type::eof(), c))
return traits_type::not_eof(c);
switch (c) {
case '\n':
case '\r': {
prefix = "[FIX]";
buffer += c;
if (buffer.size() > 1)
sbuf->sputn(prefix.c_str(), prefix.size());
int_type rc = sbuf->sputn(buffer.c_str(), buffer.size());
buffer.clear();
return rc;
}
default:
buffer += c;
return c;
}
}
std::string prefix;
std::streambuf* sbuf;
string buffer;
};
namespace multi {
class buf : public std::streambuf {
std::vector<std::streambuf *> buffers;
public:
typedef std::char_traits<char> traits_type;
typedef traits_type::int_type int_type;
buf() {}
void attach(std::streambuf *s) { buffers.push_back(s); }
void attach(std::ofstream &s) { buffers.push_back(s.rdbuf()); }
int_type overflow(int_type c) {
bool eof = false;
for (std::streambuf *buf : buffers)
eof |= (buf->sputc(c) == traits_type::eof());
return eof ? traits_type::eof() : c;
}
};
class logstream : public std::ostream {
std::vector<std::ofstream *> streams;
buf outputs;
logger log;
void attach(std::ostream &s) { outputs.attach(s.rdbuf()); }
void attach(char const *name) {
std::ofstream *s = new std::ofstream(name);
streams.push_back(s);
outputs.attach(s->rdbuf());
}
template <typename T, typename...pack>
void attach(T &t, pack&...p) {
attach(t);
attach(p...);
}
public:
template <typename...pack>
logstream(pack&...p) : log(&outputs), std::ostream(&log) { attach(p...); }
~logstream() {
for (auto d : streams) {
d->close();
// Bug: crashes with g++ if delete is allowed to execute.
//delete d;
}
}
};
}
#endif
Then the demo of how to use it:
#include "logger"
int main(){
multi::logstream l(std::cout, "c:/path/log.txt");
l << "This is a prefixed string\n";
}
Obviously the header is fairly large, but the code to use it seems (at least to me) about as simple as you can hope for -- create an object, specifying where you want the output to go, just a normal stream -- except that you can specify more than one. Then write to it like you would to any other stream, and the output goes to all of the specified outputs, with each line preceded by the specified prefix.

How do I change a C++ output stream to refer to cout?

I have a class that I want to give an output stream as a member to, to wit:
class GameBase {
protected:
ofstream m_OutputWriter;
...
}
There is a method in this class that takes a string argument and opens m_OutputWriter to point to that file, so data may be output to that file by using the standard << operator;
However, what I would like is to make the stream point to cout by default, so that if the output path is not specified, output goes to the console output instead of to a file, and it will be completely transparent by the calling class, who would use
m_OutputWriter << data << endl;
to output the data to the predetermined destination. Yet, I have tried a couple of the other examples here, and none of them exactly seem to fit what I'm trying to do.
What am I missing here?
Why does the stream need to be a member?
struct GameBase {
void out(std::ostream& out = std::cout);
// ...
};
In addition to having an std::ofstream as a member, I would use a function that returns an std::ostream&.
For example:
class GameBase {
std::ofstream m_OutputWriter;
protected:
std::ostream& getOutputWriter() {
if (m_OutputWriter)
return m_OutputWriter;
else
return std::cout;
}
...
}
A fully-functioning example:
#include <iostream>
#include <ostream>
std::ostream& get() {
return std::cout;
}
int main() {
get() << "Hello world!\n";
}

How to use my logging class like a std C++ stream?

I've a working logger class, which outputs some text into a richtextbox (Win32, C++).
Problem is, i always end up using it like this:
stringstream ss;
ss << someInt << someString;
debugLogger.log(ss.str());
instead, it would be much more convenient to use it like a stream as in:
debugLogger << someInt << someString;
Is there a better way than forwarding everything to an internal stringstream instance? If'd do this, when would i need to flush?
You need to implement operator << appropriately for your class. The general pattern looks like this:
template <typename T>
logger& operator <<(logger& log, T const& value) {
log.your_stringstream << value;
return log;
}
Notice that this deals with (non-const) references since the operation modifies your logger. Also notice that you need to return the log parameter in order for chaining to work:
log << 1 << 2 << endl;
// is the same as:
((log << 1) << 2) << endl;
If the innermost operation didn't return the current log instance, all other operations would either fail at compile-time (wrong method signature) or would be swallowed at run-time.
Overloading the insertion operator<< is not the way to go. You will have to add overloads for all the endl or any other user defined functions.
The way to go is to define your own streambuf, and to bind it into a stream. Then, you just have to use the stream.
Here are a few simple examples:
Logging In C++ by Petru Marginean, DDJ Sept 05th 2007
Rutger E.W. van Beusekom's logstream class, check also the .hpp alongside with this file
As Luc Hermitte noted, there is "Logging In C++" article which describes very neat approach to solve this problem. In a nutshell, given you have a function like the following:
void LogFunction(const std::string& str) {
// write to socket, file, console, e.t.c
std::cout << str << std::endl;
}
it is possible to write a wrapper to use it in std::cout like way:
#include <sstream>
#include <functional>
#define LOG(loggingFuntion) \
Log(loggingFuntion).GetStream()
class Log {
using LogFunctionType = std::function<void(const std::string&)>;
public:
explicit Log(LogFunctionType logFunction) : m_logFunction(std::move(logFunction)) { }
std::ostringstream& GetStream() { return m_stringStream; }
~Log() { m_logFunction(m_stringStream.str()); }
private:
std::ostringstream m_stringStream;
LogFunctionType m_logFunction;
};
int main() {
LOG(LogFunction) << "some string " << 5 << " smth";
}
(online demo)
Also, there is very nice solution provided by Stewart.
An elegant solution that also solves the flushing issues is the following:
#include <string>
#include <memory>
#include <sstream>
#include <iostream>
class Logger
{
using Stream = std::ostringstream;
using Buffer_p = std::unique_ptr<Stream, std::function<void(Stream*)>>;
public:
void log(const std::string& cmd) {
std::cout << "INFO: " << cmd << std::endl;
}
Buffer_p log() {
return Buffer_p(new Stream, [&](Stream* st) {
log(st->str());
});
}
};
#define LOG(instance) *(instance.log())
int main()
{
Logger logger;
LOG(logger) << "e.g. Log a number: " << 3;
return 0;
}
In the Logger class, override the << operator.
Click Here to know how to implement the << operator.
You can also avoid the logging statements inside the code
using Aspect Oriented programming.