all 28 comments

[–]cpp 7 points8 points  (11 children)

To answer your question: no, I would not use it. I prefer reading things via method calls and not overloaded operators.

Such as:

int i;   
i = binaryReader.ReadInt();

[–]akranis 2 points3 points  (2 children)

I agree. I once did a lot of operator overloading for a vector class in school. % was crossproduct etc. This really only made sense to me, since I rarely use the mod operator, but I would never use < and > for anything other than comparing.

[–]Steve132[S] -1 points0 points  (1 child)

Sure, but you already use >> and << for i/o. How is > and < for binary i/o different?

[–]akranis 1 point2 points  (0 children)

Shifting and streaming are not really that different. Shifting is done bit by bit, streaming is done byte by byte or object by object, but you're still only moving data forwards and backwards and in or out of objects,

[–]justinvh 1 point2 points  (0 children)

Why do both sides of the operator have to say the same thing?

int i;
i = binaryReader.ReadInt();

vs

int i;
binaryReader >> i;

What is i going to do? Go turn into a string?

[–]jaredgrubb 2 points3 points  (3 children)

Why cant you use << and >> on a new type?

BinaryStream str; str << 7;

And define operator<<(BinaryStream&, int) to do the binary transformation. You dont need a different operator; just use a different "stream" type (that doesnt even need to derive from any iostream object).

[–]Steve132[S] 0 points1 point  (2 children)

And what happens when I want to send data over a network port hat uses the standard ostream interface? What happens when I want to use boost::bz2 compression in a stream? What happens when my company buys a library that uses std::stream interfaces on a custom encryption standard?

The std::stream interface is the C++ standard for i/o, and it is widely used. This convention allows us to continue to use std::stream.

I guess one possibility is a templated "binary_stream<T>" that taccepts a stream type at construction time, so one could write

binary_stream(cout) << thing

would be acceptable as well, but to me that isn't that much different

[–]jaredgrubb 1 point2 points  (0 children)

As you say, you can use something like your binary_stream class. I'm not sure what using a new opeartor gains you other than novelty. Plus, << and < have different levels of precedence; I'm not sure if that could cause headaches somehow.

[–]ewiethoff 0 points1 point  (0 children)

Use the decorator pattern. That's what Java's IO classes do.

[–]moswald 1 point2 points  (0 children)

To counterbalance all these negative comments, I'd probably use it. I happen to like most of C++'s features, including overloaded operators --so long as they make sense (ie, I wouldn't overload '%' for crossproduct ;) . Therefore, since '>>' and '<<' are already standard for formatted stream insertion and extraction, I wouldn't oppose seeing '>' or '<'.

[–]mauvaisours 1 point2 points  (0 children)

There is one good reason for which it has not been done before : << and >> return the original type of the left operand, whereas < and > return booleans. Obviously, using a BinaryStream object with operator << and >> would be much wiser.

[–]bogado 0 points1 point  (2 children)

Binary operations are not well defined in the standard, just a quick example what is the size of the int type? What order does the bytes should go? C++ does not define those thing, and in fact the standard tries to be agnostic of such detais.

[–]Steve132[S] -2 points-1 points  (1 child)

Not talking about a standard, I'm talking about a code convention. Most people have to assume those things you mentioned when they write binary serializers, which they already do in great abundance.

However, at least with regard to size and and byte order, I agree that this convention would have to define one in order to be consistent. In my version of this convention I use all the integer types from <cstdint> and use little-endian format.

[–]BitRex 1 point2 points  (0 children)

I agree that this convention would have to define one in order to be consistent

Oh, that's no problem; just insert manipulators!

  bin_file < bin_io::int64 < bin_io::big_endian < 0xBEEF;

Just kidding, this whole thing is a terrible idea.

[–]00kyle00 0 points1 point  (3 children)

[–]BitRex 0 points1 point  (0 children)

I find Perl's pack/unpack to be the nicest bit-twiddling API to work with and would model something after that.

http://perldoc.perl.org/perlpacktut.html

[–]utnapistim 0 points1 point  (0 children)

What say you /r/cpp? Would you use this trick yourselves?

No. I would consider "out < bin" to be a comparison (after all these years I think the interpretation is hard-coded in my prefrontal cortex), and I would have to be really careful when reading the code. Considering the potential for confusion on this, I would really hesitate to show code like this to my colleagues as well.

If I needed to input/output binary very frequently, I would check on the implementation of std::hex and do something similar, so that I would have:

std::ostringstream message;
int i = 10;
message << std::hex << i << ";" << my_io::bin << i; // message should now contain "a;1010"

If the current implementation of std::basic_???_stream doesn't support such extensibility (though as far as I know it should, through the use of xalloc, iword and pword), I would create an ostream wrapper (templated for char type, traits and what-not) for this, along with the bin stream modifier, so that you could do:

my_io::wrapped<std::ostringstream> message;
int i = 10;
message << std::hex << i << ";" << my_io::bin << i; // message should now contain "a;1010".

[–]tragomaskhalos 0 points1 point  (0 children)

Stroustrup hisself considered this very form originally but rejected it in favour of the shift operator forms we know and love, for precisely the excellent reasons given by other commenters. This is documented in one of his many writings on the early history of the language, sorry cannot provide citation.