Have a C++ Class act like a custom ostream, sstream - c++

I have a C++ class MyObject and I want to be able to feed this data like I would to a osstream (but unlike a direct sstream, have the incoming data be formatted a special way). I can't seem to figure out how to overload a operator for MyObject to eat input given to it.
class MyObject {
public:
ostringstream s;
FEEDME
};
int main() {
MyObject obj;
obj.FEEDME << "Hello" << 12345;
// I want obj.s == ":Hello::12345:"
}
I want it so every item fed in be surrounded by : :
So in the given example, s = ":Hello::12345" should be the final outcome. What my question is, how can I tell the object that when ever a <<something, put : : around the something.
Is this possible?

try this:
class MyObject {
public:
template <class T>
MyObject &operator<<(const T &x) {
s << ':' << x << ':';
return *this;
}
std::string to_string() const { return s.str(); }
private:
std::ostringstream s;
};
MyObject obj;
obj << "Hello" << 12345;
std::cout << obj.to_string() << std::endl;
There are certain things you won't be able to shove into the stream, but it should work for all the basics.

You may find the answers for How do I create my own ostream/streambuf? helpful.

I would take a slightly different approach and create a formater object.
The formater object would then handle the inserting of format character when it is applied to a stream.
#include <iostream>
template<typename T>
class Format
{
public:
Format(T const& d):m_data(d) {}
private:
template<typename Y>
friend std::ostream& operator<<(std::ostream& str,Format<Y> const& data);
T const& m_data;
};
template<typename T>
Format<T> make_Format(T const& data) {return Format<T>(data);}
template<typename T>
std::ostream& operator<<(std::ostream& str,Format<T> const& data)
{
str << ":" << data.m_data << ":";
}
int main()
{
std::cout << make_Format("Hello") << make_Format(123);
}

Related

Autodeduction of return type

After reading C++ auto deduction of return type and C++ : Vector of template class, I'm still wondering how to do generic operations (e.g. operator << overload) on object. My code looks like
#include <map>
#include <memory>
#include <string>
#include <iostream>
/**
* Abstract placeholder for Cache polymorphism
*/
class ICache
{
public:
virtual void update() {};
friend std::ostream & operator << (std::ostream & out, const ICache & IC)
{
out << "you should never print this";
}
};
/**
* Concrete. Coupling a name with some cached value
*/
template<typename T>
class Cache :
public ICache
{
const std::string m_name;
T m_cached;
public:
Cache(const std::string & name) :
m_name(name),
m_cached(0)
{}
void update() override
{
// m_cached is synced with remote resource; action depends both from T and m_name
}
void set(const T t)
{
std::cout << m_name << " setting " << +m_cached << " -> " << +t << std::endl;
m_cached = t;
}
inline T get() const noexcept { return m_cached; }
friend std::ostream & operator << (std::ostream & out, const Cache & O)
{
out << "Cache<" << O.m_name << ", " << O.m_cached << ">";
}
};
class CacheMap
{
std::map<std::string, std::unique_ptr<ICache>> m_map;
template<typename T>
Cache<T>* _get_ptr(const std::string & name) const
{
return reinterpret_cast<Cache<T>*>(m_map.at(name).get());
}
public:
template<typename T>
T get(const std::string & name) const
{
return _get_ptr<T>(name)->get();
}
template <typename T>
void set(const std::string & name, T t)
{
_get_ptr<T>(name)->set(t);
}
template <typename T>
void insert(const std::string & name, T def = 0)
{
std::unique_ptr<ICache> up = std::make_unique<Cache<T>>(name);
m_map.insert({name, std::move(up)});
set<T>(name, def);
}
friend std::ostream & operator << (std::ostream & out, const CacheMap & OM)
{
out << "OM{";
for (const auto & IO : OM.m_map)
out << IO.first << ": " << *(IO.second.get()) << ", "; // ver1
// out << IO.first << ": " << (IO.second->get()) << ", "; // ver2
out << "}";
return out;
}
};
int main()
{
CacheMap m;
int i= 70000;
m.insert<int>("i", 69999);
m.insert<short>("s", 699);
m.insert<char>("c", 69);
m.set("i", i);
std::cout << m << std::endl;
}
Line marked with trailing //ver1 shows you should never print this which makes sense; I'm dealing with std::unique_ptr<ICache> objects.
Line marked with trailing //ver2 won't compile at all, and this makes sense too.
What I'd like to do inside CacheMap is to auto-detect, at runtime (hmm sounds bad) the correct T, given a map key, in order to fire the right reinterpret_cast<> and to retrieve m_cached value.
EDIT 1
If compiling with g++ -O3, ver1 line causes a segmentation violation.
Just use a virtual function. The time you cast your variable from Cache<int> pointer type to ICache pointer you lose compile time information about it. That information is lost. You can use dynamic_cast in your friend ICache::operator<< to handle all the different types... To properly resolve type information use virtual functions - ie. unique data tied to each of the class.
#include <map>
#include <memory>
#include <string>
#include <iostream>
class ICache
{
public:
virtual ~ICache() {};
virtual void update() {};
// -------- HERE --------------
virtual std::ostream& printme(std::ostream & out) const = 0;
friend std::ostream& operator << (std::ostream & out, const ICache & IC) {
return IC.printme(out);
}
};
template<typename T>
class Cache : public ICache {
const std::string m_name;
T m_cached;
public:
Cache(const std::string & name): m_name(name), m_cached(0) {}
void update() override {}
void set(const T t) {
std::cout << m_name << " setting " << +m_cached << " -> " << +t << std::endl;
m_cached = t;
}
inline T get() const noexcept { return m_cached; }
std::ostream& printme(std::ostream & out) const override {
out << "Cache<" << m_name << ", " << m_cached << ">";
return out;
}
};
class CacheMap {
std::map<std::string, std::unique_ptr<ICache>> m_map;
template<typename T>
Cache<T>* _get_ptr(const std::string & name) const {
return dynamic_cast<Cache<T>*>(m_map.at(name).get());
}
public:
template<typename T>
T get(const std::string & name) const {
return _get_ptr<T>(name)->get();
}
template <typename T>
void set(const std::string & name, T t) {
_get_ptr<T>(name)->set(t);
}
template <typename T>
void insert(const std::string & name, T def = 0) {
std::unique_ptr<ICache> up = std::make_unique<Cache<T>>(name);
m_map.insert({name, std::move(up)});
set<T>(name, def);
}
friend std::ostream& operator << (std::ostream & out, const CacheMap & OM) {
out << "OM{";
for (const auto & IO : OM.m_map)
out << IO.first << ": " << *(IO.second.get()) << ", "; // ver1
// out << IO.first << ": " << (IO.second->get()) << ", "; // ver2
out << "}";
return out;
}
};
int main()
{
CacheMap m;
int i= 70000;
m.insert<int>("i", 69999);
m.insert<short>("s", 699);
m.insert<char>("c", 69);
m.set("i", i);
std::cout << m << std::endl;
}
will output on godbolt:
i setting 0 -> 69999
s setting 0 -> 699
c setting 0 -> 69
i setting 69999 -> 70000
OM{c: Cache<c, E>, i: Cache<i, 70000>, s: Cache<s, 699>, }
I just spotted, to protect against very bad and hard to debug errors, I remind you to use dynamic_cast instead of reintepret_cast in CacheMap::_get_ptr().
There are various ways, but generally I would implement a single operator<<() that calls a virtual function.
class ICache {
protected: // so the function is only accessible to derived classes
virtual std::ostream print(std::ostream &out) const = 0; // force derived classes to override
friend std::ostream &operator<<(std::ostream &out, const ICache& c);
};
Then place a single definition of the operator<< in a single compilation unit
// definition of class ICache needs to be visible here
std::ostream &operator<<(std::ostream &out, const ICache& c)
{
return c.print(out);
}
And to implement the derived class
// definition of ICache here
template<class T>
class Cache: ICache
{
protected:
std::ostream print(std::ostream &out) const override
{
// output a Cache<T>
return out;
}
};
The advantage of this is that each class takes responsibility for outputting itself, rather than a container class having to work out which output function to call (and the opportunity for a programmer to forget to do that).
First, reinterpret_cast is a dangerous thing. In contexts of polymorphism you mostly want to use dynamic_cast.
You problem is not about templates etc at all, but it is more about that you want to make the operator<< virtual, which is not possible, since it is a friend function. An easy workaround is the following:
class ICache {
virtual void print(std::ostream &out) const { // Prefer pure virtual
out << "Never print this\n";
}
friend std::ostream &operator<<(std::ostream &out, const ICache& c) {
c.print(out);
return out;
}
};
template<class T>
class Cache: ICache {
void print(std::ostream &out) const override {
out << "Print this instead\n";
}
};
will do what you want without any casting.

Superclass for ostream and fstream

I'm trying to make my own logging class in C++ using a wrapper class in which i overloaded operator<< that sends it to the cout. Now I want to change it, so that when i create instance of that class, i can pass and argument that logs data in std::cout or some file i create. What is the exact type that is superclass of both fstream and ostream? I tried with std::ios&, std::basic_ios&, std::basic_ostream& and none of them seems to work (throwing me compilation error).
class myostream {
public:
static int getlogLevel() {
return loglevel;
}
static void setlogLevel(int i) {
loglevel = i;
}
myostream(std::basic_ios& cout, int level)
: _cout(cout), _level(level)
{}
template<class T>
std::ostream& operator<<(T t) {
if(_level >= loglevel) {
_cout << loglevelcolor[_level] << loglevelname[_level] << " " << t << COL_RESET << std::endl;
}
return _cout;
}
private:
static int loglevel;
std::basic_ostream& _cout;
int _level;
};
Use base class std::ostream which is typedef for basic_ostream<char>, reference: iostream hierarchy.
Works for me (std::cout, std::ofstream):
#include <iostream>
class myostream {
public:
myostream(std::ostream& out)
: _out(out) {}
template<class T>
std::ostream& operator<<(T t) {
_out << "test" << " " << t << '\n' << 42 << std::endl;
return _out;
}
private:
std::ostream& _out;
};
What is the exact type that is superclass of both fstream and ostream?
It is std::ostream, which is an alias to std::basic_ostream<char>. See the class diagram for std::fstream.
Example:
class myostream {
public:
myostream(int level) // Log into stdout.
: _cout(std::cout), _level(level)
{}
myostream(char const* filename, int level) // Log into a file.
: _file(filename), _cout(_file), _level(level)
{
if(!_file.is_open())
throw std::runtime_error("Failed to open " + std::string(filename));
}
// ...
private:
std::ofstream _file;
std::ostream& _cout;
int _level;
};

operator << overloading in a constructor

I'm debugging a program and I would like to make printing from that pattern:
std::cout << firstVar << ", " << secondVar << ", " << thirdVar << endl ;
shorter, i.e, the same thing should happen if we will write the code:
shortPrint(std::cout) << firstVar << secondVar << thirdVar;
note: there is no limit for the variables quantity, it can be 1 and it can be 20, so that should also work:
shortPrint(std::cout) << firstVar << secondVar << thirdVar << anotherVar << oneMoreVar;
Someone told me that the easiest wat to do that is to create class that is called "shortPrint".
Can anyone help me figuring this out?
For start, I would say that I only need to implement a constructor and operator << overloading, but I'm not sure how to do that exactly in that case.
Yes create a shortPrint class with an appropriate overloaded operator. Something like this :
class shortPrint {
ostream &o;
public:
shortPrint(ostream &o) : o(o) {}
template <typename T> shortPrint &operator<<(const T &t) {
o << t << ',';
return *this;
}
// support for endl, which is not a value but a function (stream->stream)
shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
o << pf;
return *this;
}
};
That should work (basically).
To eliminate the problem of extra commas use this :
class shortPrint {
class shortPrint2{
shortPrint &s;
public:
shortPrint2(shortPrint &s) : s(s) {}
template <typename T> shortPrint2 &operator<<(const T &t) {
s.o << ',' << t ;
return *this;
}
shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
s.o << pf;
return s;
}
};
ostream &o;
shortPrint2 s2;
public:
shortPrint(ostream &o) : o(o), s2(*this) {}
template <typename T> shortPrint2 &operator<<(const T &t) {
o << t;
return s2;
}
shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
o << pf;
return *this;
}
};
You can do something like the following:
class _ostream_wrap
{
public:
template <class T>
_ostream_wrap& operator << (const T & v)
{
m_ost << "[ " << v << " ]";
return (*this);
}
explicit _ostream_wrap(std::ostream & ost)
:m_ost(ost)
{}
private:
std::ostream& m_ost;
};
template <class OSTREAM>
_ostream_wrap shortPrint(OSTREAM & o)
{
return _ostream_wrap(o);
}
//...
shortPrint(std::cout) << 1 << 2;
however this implementation will not work on rvalues:
//you can't do something like the following:
shortPrint(MyOstream(some_args)) << 1;
This is because the class _ostream_wrap keeps a reference to the stream and for rvalues case it needs to make a copy. To make a copy you need to have two implementations (this would be the final version):
template <class OSTREAM>
class _ostream_wrap
{
public:
template <class T>
_ostream_wrap<OSTREAM>& operator << (const T & v)
{
m_ost << "[ " << v << " ]";
return (*this);
}
public:
//the constructor is harder to write so i decided
//that for this i will keep the member public
OSTREAM m_ost;
};
template <class OSTREAM>
_ostream_wrap<OSTREAM&> shortPrint(OSTREAM & o)
{
_ostream_wrap<OSTREAM&> rvalue;
rvalue.m_ost = o;
return rvalue;
}
template <class OSTREAM>
_ostream_wrap<OSTREAM> shortPrint(const OSTREAM & o)
{
_ostream_wrap<OSTREAM> rvalue;
rvalue.m_ost = o;
return rvalue;
}
Here's something with very basic functionality:
#include <iostream>
struct shortPrint {
explicit shortPrint(std::ostream& os)
: strm(&os), first(true) {}
template<typename T>
shortPrint& operator<<(T&& t)
{
if (first) {
first = false;
} else {
*strm << ", ";
}
*strm << std::forward<T>(t);
return *this;
}
shortPrint& operator<<( std::ostream& (*func)(std::ostream&) )
{
*strm << func;
return *this;
}
private:
std::ostream* strm;
bool first;
};
int main()
{
int i = 3;
shortPrint(std::cout) << "1" << 2 << i << std::endl;
shortPrint(std::cout) << 4;
}
The tricky part is getting the commas to be printed correctly. I chose to print them before every streamed object, except before the very first one. As you can see, there's one general operator<< template that simply prints the comma and forwards the argument. The next problem are stream manipulators, because we don't want to print commas before them. The other operator<< overload takes care of that. If you want to be more generic, there's two more you need to take care of (see no. 9 here ).
Hope that helps.
Return the ostream from the function. Something like:
std::ostream &shortPrint(std::ostream &out) {
//whatever you need here
return out;
}
Edit: you the kind of formatting you need, you need to make a class with overloaded stream operator that returns the class. But you need to keep the reference to the needed stream in the class.

C++ Wrap cin and cout in class - Overload << and >> operators

I am trying to make a Console class. I would like to wrap cin and cout in the class and overload the << and >> operators. So I could use the class as such:
// Output
Console << "Call cout from Console" << endl;
// Input
string str;
Console >> str; // Call cin
My best guess was:
class Console {
//...
public:
ostream& operator<< (ostream& os)
{
cout << os;
return &cout;
}
//...
};
But I know that's wrong, how could I overload the operators to use the Console class as both cin and cout?
I got a working code that can handle the stream manipulators. You can see my code in action in this Ideone page
Here is the code:
#include <iostream>
typedef std::ostream& (*manip) (std::ostream&);
class console {
};
template <class T> console& operator<< (console& con, const T& x) { std::cout << x; return con; }
template <class T> console& operator>>(console& con, T& x) { std::cin >>x; return con; }
console& operator<< (console& con, manip manipulator){ std::cout<<manipulator; return con;}
int main() {
console c;
int a,b;
c>>a>>b;
c << "hello world"<<std::endl<<std::hex<<(a+b)<<std::endl;
}
Thanks #MooingDuck for the discussion that led me to a working answer and #111111 for the start point.
I don't know why would want to do such a thing but it isn't the stream you need to capture but the other type. But if this is just to make std::cout and std::cin more convenient I wouldn't bother.
class console {
};
template<typename T>
console& operator<<(console con, const T& val) {
std::cout << val;
return con;
}
console c;
c << "hello world\n";
This is not direct answer to your question, but maybe I point you out some alternative.
See my answer to some other question. To define yourself all of these <<and >> operators is not very easy. However you can overwrite streambuf for Console. Use combined streambufs of cin and cout,
Derive your console from std::iostream and your streambuf from std::streambuf
class console_streambuf : public std::streambuf {
public:
console_streambuf() {
// no buffering, overflow on every char
setp(0, 0);
}
virtual int_type overflow(int_type c) {
std::cout << c;
return c;
}
...
};
class console : public std::iostream {
public:
console() { rdbuf(&buf); }
private:
console_streambuf buf;
};
Contrary to many of the answers above, doing what you want is pretty simple, using the magic of templates.
I'd recommend using a stringstream, because using an ostream (cout is an ostream) can require arcane black magic (no joke).
#include <string>
#include <iostream>
#include <sstream>
struct console {
std::stringstream data_;
console() : data_() { };
// We make ourselves a template sink so we can "take" operator<<'s.
// The awesome advantage to using a template like this is that the
// compiler will allow us to "take" any data that can be converted
// to a stringstream, which will handle converting int's etc.
// for us!
template<typename T>
console& operator<<(const T& what) {
data_ << what;
return *this; // We must return a reference if we want to
// string together more than one thing, i.e.
// b << " " << 4;
}
void flush() {
std::cout << data_.str();
data_.clear();
std::cout.flush();
}
};
int main()
{
int a = 4;
console b;
console c;
b.data_ << 2;
c.data_ << 4;
//b << std::cout; // WHAT? it's possible but stupid, prints garbage
// Because we made the template return a reference, this will
// allow us to chain things just like we do with cout.
b << " HELLO WORLD! " << "yo!" << 4;
b << a << " " << 4.2f;
// Compiler chokes on this. It will try to convert "console"
// to a stringstream which it can't.
//b << c;
b.flush(); // Send out the output
// Wait for key press
char foo[500];
gets(foo);
}
Output:
2 HELLO WORLD! yo!44 4.2
Just like cout, except of course with more control.
You can get into using basic_ostream's and basic_istreams if you want binary I/O, but I'd recommend against it unless you really really need it.
Overloaded operator functions must be declared with the specific types you're going to call them with on the left and right. So you will need an operator<< (int), operator<< (double), operator<< (const std::string &), etc.
If you're really just going to pass them on to cin and cout, you can save typing by using a template member function, like:
template <class T> Console& operator<< (const T& x) { cout << x; return *this; }
[thanks to André for pointing out it should return Console& so you can string together calls like Console << a << b; ]

Better cout a.k.a coutn;

Guys would it be difficult to write coutn which would basically place newline symbol at the end of the input. While working with console (that's all I can do at the moment) I'm finding very tedious to write '\n' every time I want the line to be a new line.
Or maybe it is already implemented?
To circumvent the multiple injections on a single line, you could use a temporary object. This temporary object would add the '\n' in its destructor.
struct coutn {
coutn(): os(cout) {}
~coutn() { os << '\n'; }
template <typename T>
coutn & operator<<(T const & x) { os << x; return *this; }
private:
ostream &os;
};
coutn() << "Hello " << "World" << "!";
In the end, I'm wondering if this coutn is actually better?
Well, the first obvious thing would be to implement some kind of wrapper around it:
class Print
{
public:
explicit Print(std::ostream& stream = std::cout): mStream(stream) {}
~Print() { mStream << '\n'; }
template <class T>
Print& operator<<(T const& t) { mStream << t; return *this; }
private:
std::ostream& mStream;
};
Usage is like such:
int main(int argc, char* argv[])
{
Object object;
Print() << "My new object value: " << object;
std::ofstream file("file.log");
Print(file) << "My new object value: " << object;
}
Easy, Peasy.
Roughly:
struct StreamFilterN
{
ostream & os;
StreamFilterN(ostream & os_) : os(os_) {}
template <typename T>
StreamFilterN & operator<<(T const & x) { os << x << "\n"; return *this; }
}
StreamFilterN coutn(cout);
coutn << "Hello world";
coutn << "Yeah, like.";
(I'm not sure if this works perfectly, but it should get you started)
The way that streams work is that they add one thing and then return itself.
so are you sure you'd want to do what you're asking?
For example:
s << "a" << "b";
Would put:
a
b
Surely you can find a way with some kind of wrapper but the extra overhead incurred and the diminished code readability I don't think is worth it. Most coders are familiar with standard C++. Most coders are not familiar with your coutn and how it works.
Come one people. You must admit that C++'s newlines are too verbose. Look at C#, D, Java, Python, Ruby, should I go on? I don't think you should implement a coutn. I think you'd be better off following D's example with write, writeln, writef, and writefln variadic template functions.
Anyway here is how to do it without macros and with out needing to explicitly create temporaries.
class coutn_t
{
private:
class newliner
{
public:
explicit newliner(std::ostream & out=std::cout) : m_out(out) { }
template<typename T>
newliner& operator<<( const T& t)
{
m_out << t;
return *this;
}
~newliner() { m_out << std::endl; }
private:
std::ostream & m_out;
};
public:
// NOTE: these return by value. Only one newliner will be
// destructed however as RVO will eliminate the copy.
newliner operator()( std::ostream& out )
{ return newliner(out); }
template< typename T >
newliner operator<<( const T& t )
{
std::cout << t;
return newliner(std::cout);
}
};
coutn_t coutn;
coutn << "Hello World!";
coutn << "Hello " << "World" << '!';
std::ofstream file("ouput.txt");
coutn(file) << "Hello World" << " via file";
The complete solution will have to add more overloads for operator<< to handle stream manipulators (std::hex etc). The functions returning newliners must always be inline to allow RVO.