Using a mixin (?) to make stream i/o easier - c++

Since many students I work with on common code have some problems comprehending proper stream operator overloading, I tried to create a helper template (don't know if this is a real mixin) to facilitate the code and insure correct operator implementation. Here it comes:
template<typename T> struct IoEnabled {
friend std::ostream& operator<<(std::ostream& out, T const& val) {
return val.print(out);
}
friend std::istream& operator>>(std::istream& in, T& val) {
return val.scan(in);
}
friend QTextStream& operator<<(QTextStream& out, T const& val) {
return val.print(out);
}
friend QTextStream& operator>>(QTextStream& in, T& val) {
return val.scan(in);
}
friend QDebug operator<<(QDebug dbg,T const& val){
std::stringstream myStream;
myStream << val;
dbg.nospace() << myStream.str().c_str();
return dbg;
}
};
Inheriting class:
class Foo: private IoEnabled<Foo> {
protected:
int mData;
public:
template<typename U>
U& scan(U& in) {
in >> mData;
return in;
}
template<typename U>
U& print(U& out) const {
out << mData;
return out;
}
}
The downsides of this implementation as far as I see them at the moment:
Does not work for 3rd party types
Includes inheritance and thus tight coupling with the IoClass although not every user might need
Io for a certain type
The ups:
It works ;-)
Similar stream classes can be added without modifying all classes and withou writing specific new code for every class
Since I'm not very experienced in the usage of mixins and tend to violate coding guidelines once in a while, I'd like to know if this is an appropriate usage of a mixin or how one could obtain a similar effect with another more suitable technique.
Many Thanks, Martin

If they can write scan and print template functions, they might as well write templated operators directly, skipping this entire silly mixin business.
struct Foo {
int mData;
Foo() : mData(mData) {}
};
template <typename OutputStream>
OutputStream& operator<<(OutputStream& stream, const Foo& data) {
stream << data.mData;
return stream;
}
template <typename InputStream>
InputStream& operator>>(InputStream& stream, Foo& data) {
stream >> data.mData;
return stream;
}
Also, that special-cased QDebug overload looks entirely unnecessary and wrong.

Related

How to create a custom std::ostream which has an override for each primitive type

I am creating a custom logger that I want to use as a drop-in replacement for a std::ostream. I want to have overrides for each primitive type -- I do not want to implement a char-based streambuf thing (as you can see, I write to std::cerr anyway for now).
I'm getting a segfault with the following... I am not sure why. I've tried running in the debugger but even when I single-step through things, it's not clearly showing me why the segfault is occurring.
#include <iostream>
// A custom basic_ostream that has an implementation for each primitive type
struct Log : std::basic_ostream<char>
{
Log& operator<<(int o) noexcept { std::cerr << "INT\n"; return *this; }
};
// I want my objects to keep using std::ostream
struct A
{
friend std::ostream& operator<<(std::ostream& os, A const& o) noexcept
{
return os << o.x;
}
private:
int x;
};
int main()
{
Log log;
A a;
log << a;
}

Setting std::io_base flags for custom stream class

I have a custom class called Stream
class Stream
public:
Stream& operator<<(int i) { stream_ << i; return *this;}
template <typename CustomClass>
Stream& operator<<(const CustomClass& c) { stream_ << c.toString() /* assume this template always have toString(); return *this; }
private:
std::stringstream stream_;
};
This is a very basic example of what I actually have. And I am trying to set std::ios_base flags like following:
Stream() << 1 << std::hex << 2;
using operator;
Stream& operator<<(std::ios_base& b) { stream_.setf(b.flags()); return *this; }
from what I understand, because std::hex returns std::ios_base so it should call this and set streams' flag. But it always call the template. Note: If i remove this template, everything works just as good as you would expect but is there a way to have both?
Please feel free to ask further if you need more clarification
IOStream manipulators are not objects of type std::ios_base, they are functions that take and return std::ios_base references. So when you want to do stream insertion regarding these objects, you have to overload for function pointers:
Stream& operator<<(std::ios_base& (*manip)(std::ios_base&))
// ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
{
manip(this->stream);
return *this;
}

Enabling Classes for Use with boost::lexical_cast

Code snippet from lexical_cast:
class lexical_castable {
public:
lexical_castable() {};
lexical_castable(const std::string s) : s_(s) {};
friend std::ostream operator<<
(std::ostream& o, const lexical_castable& le);
friend std::istream operator>>
(std::istream& i, lexical_castable& le);
private:
virtual void print_(std::ostream& o) const {
o << s_ <<"\n";
}
virtual void read_(std::istream& i) const {
i >> s_;
}
std::string s_;
};
std::ostream operator<<(std::ostream& o,
const lexical_castable& le) {
le.print_(o);
return o;
}
std::istream operator>>(std::istream& i, lexical_castable& le) {
le.read_(i);
return i;
}
Based on document,
template<typename Target, typename Source>
Target lexical_cast(const Source& arg);
1> Returns the result of streaming arg into a standard library
string-based stream and then out as a Target object.
2> Source is OutputStreamable
3> Target is InputStreamable
Question1> For User Defined Type (UDT), should the OutputStreamable or InputStreamable always have to deal with std::string? For example, given a class containing a simple integer as member variable, when we define the operator<< and operator>>, what is the implementation code looks like? Do I have to convert the integer as a string? Based on my understanding, it seems that UDT always has to deal with std::string in order to work with boost::lexical_cast and boost::lexcial_cast needs the intermediate std::string to do the real conversion jobs.
Question2> Why the return value of operator<< or operator>> in above code is not reference to std::ostream& or std::istream& respectively?
To make your class usable with lexical_cast, just define the "stream" operators for it.
From Boost.LexicalCast Synopsis:
Source is OutputStreamable, meaning that an operator<< is defined that takes a std::ostream or std::wostream object on the left hand side and an instance of the argument type on the right.
Target is InputStreamable, meaning that an operator>> is defined that takes a std::istream or std::wistream object on the left hand side and an instance of the result type on the right.
Target is CopyConstructible [20.1.3].
Target is DefaultConstructible, meaning that it is possible to default-initialize an object of that type [8.5, 20.1.4].
:
// either inline friend, out-of-class friend, or just normal free function
// depending on whether it needs to access internel members
// or can cope with the public interface
// (use only one version)
class MyClass{
int _i;
public:
// inline version
friend std::ostream& operator<<(std::ostream& os, MyClass const& ms){
return os << ms._i;
}
// or out-of-class friend (friend declaration inside class only)
friend std::ostream& operator<<(std::ostream& os, MyClass const& ms);
// for the free function version
int get_i() const{ return _i; }
};
// out-of-class continued
std::ostream& operator<<(std::ostream& os, MyClass const& ms){
return os << ms._i;
}
// free function, non-friend
std::ostream& operator<<(std::ostream& os, MyClass const& ms){
return os << ms.get_i();
}
The same of course for operator>>.

C++ distinguishing structurally identical classes

I have several types that share common behaviour and with same constructors and operators. Some look like this:
class NumberOfFingers
{
public:
void operator=(int t) { this->value = t; }
operator int() const { return this->value; }
private:
int value;
};
NumberOfToes is identical.
Each class has different behaviour, here is an example:
std::ostream& operator<<(std::ostream &s, const NumberOfFingers &fingers)
{
s << fingers << " fingers\n";
}
std::ostream& operator<<(std::ostream &s, const NumberOfFingers &toes)
{
s << toes << " toes\n";
}
How can I minimise the duplication in the class definitions, whilst keeping class types distinct? I don't want to have NumberOfFingers and NumberOfToes derive from a common base class because I lose the constructor and operators. I would guess a good answer would involve templates.
Yes, you are correct in that it would involve templates :)
enum {FINGERS, TOES...};
...
template<unsigned Type> //maybe template<enum Type> but I havent compiled this.
class NumberOfType
{
public:
void operator=(int t) { this->value = t; }
operator int() const { return this->value; }
private:
int value;
};
...
typedef NumberOfType<FINGERS> NumberOfFinger
typedef NumberOfType<TOES> NumberOfToes
... so on and so forth.

how to template for operator<< for ostream

The following won't compile for me. I'm out of ideas... Any help?
template<>
inline
std::ostream& operator<< <const std::map<std::string, std::string> > (std::ostream& stream, const std::map<std::string, std::string>& some_map)
{
return stream;
}
g++ gives me the following error:
error: expected initializer before '<' token
Edit: 1
Okay, since everyone is telling me to overload, let me give you an example that wouldn't make sense for overloading. What if I have this:
template <typename T>
inline
std::ostream& operator<<(std::ostream& stream, const T& something)
{
stream << something.toString();
return stream;
}
class Foo
{
public:
Foo(std::string s)
{
name = s;
}
std::string toString() const
{
return name;
}
private:
std::string name;
};
class Bar
{
public:
Bar(int i)
{
val = i;
}
std::string toString() const
{
std::ostringstream stream;
stream << val;
return stream.str();
}
private:
int val;
};
int main(int, char**)
{
Foo foo("hey");
Bar bar(2);
std::cout << foo << std::endl;
std::cout << bar << std::endl;
return 0;
}
Now this won't work either.
I just want to avoid having to overload operator<< over and over by using a template like above. This seems like it should be possible. I would like to know if it is, and if so, how?
In such a scenario, overloading for both Foo and Bar to do the same thing would be a waste, that is why I am trying to avoid it.
Edit: 2
Okay, it appears that I am being misunderstood. Here is another attempt to clarify:
template <typename T>
std::ostream& operator<<(ostream& stream, const T& t)
{
for(typename T::const_iterator i = t.begin(), end = t.end(); i != end; ++i)
{
stream << *i;
}
return stream;
}
int main(int, char**)
{
set<int> foo;
list<string> bar;
vector<double> baz;
cout << foo << " " bar << " " << baz << endl;
};
The above code won't work mind you. Complains about ambiguity. But it seems like the better solution for printing out containers. If I did it the with overloading, I would need to write a version of operator<< for each container/datatype combination, which would yield a ridiculous amount of code duplication.
This doesn't need to be a template function.
std::ostream & operator<<(std::ostream & stream, const std::map<std::string, std::string> & some_map)
{
return stream;
}
Edit:
In reference to my comment about writing Java in C++(and sorry if it sounded rude, I didn't intend to be smarmy). Tell me if this doesn't work better for you. Instead of writing a "toString" method in the first place, just overload the operator<< to begin with. The function is nearly identical. Then, you can write a non-member template toString function that will automatically work with all of your classes, like this:
#include <sstream>
#include <string>
template<typename T>
std::string toString(const T & val)
{
std::ostringstream ostr;
ostr << val;
return ostr.str();
}
Edit 2
Here's my alternative if you still insist on doing it your way. Make all of your classes with the toString method inherit from an abstract class with a virtual toString method, then write one operator<< to handle all of them.
class Stringifiable
{
public:
virtual std::string toString() const = 0;
};
std::ostream & operator<<(std::ostream & ostr, const Stringifiable& something)
{
return ostr << something.toString();
}
Now the compiler will choose your overload over templates.
You can use SFINAE to remove the template overload from consideration. Note that this has to be a part of the signature of the function. Thus you can use boost::enable_if:
template < typename T >
typename boost::enable_if< meta_function_to_check_for_concept<T>, std::ostream&>::type
operator << (std::ostream & out, T const& t)
{
...
}
If you don't do this then your template will attempt to match almost anything and will explode for every use of << that is not in line with the concept you're trying to match.
Your example is a bit contrived and might not lend itself to this answer, but there are situations in which it's warranted. This is how to do it.
In Crazy Eddie's answer, he mentions SFINAE. Now, C++11 has that built in. If all types derive from the same base class, this is made pretty simple. Here's a more complete example using C++11:
#include <type_traits>
#include <iostream>
#include <ostream>
class MyBaseType {};
class MyClass : MyBaseType {};
class MyOtherClass : MyBaseType {};
class SomeType {};
template <typename T>
typename std::enable_if<std::is_base_of<MyBaseType,T>::value,std::ostream&>::type
operator<<(std::ostream& out, const T& x)
{
out << 1;
}
int main()
{
MyBaseType x;
MyClass y;
MyOtherClass z;
SomeType i;
std::cout << x << y << z; // success!
std::cout << i; // compile-time failure!
}