3

I am trying to overload the stream operator as a diagnostic tool for various objects in my code. Ideally I would like to be able to modify the stream on the fly with those stream modifier flags, however these are very limited and I don't really want to sprinkle setVerbose flags in each of my objects. I ended up with the following rather poor but working solution

#include <iostream> #include <string> #include <vector> struct StructA { std::string mLongName; std::string mShortName; inline friend std::ostream& operator << (std::ostream& os, const StructA& rStruct) { // I dont know how to use a generic verbose flag - so use this - very bad idea // but perhaps the stackoverflow people can help out with a good suggestion if (os.flags() & os.skipws) { os << rStruct.mShortName << std::endl; } else { os << rStruct.mLongName << std::endl; } return os; } }; int main() { StructA test {"Verbose Name", "Short Name"}; std::cout << test << std::noskipws << test << test << std::skipws << test; } 

I created the above live example to demonstrate my point, and it prints the following output:

Short Name Verbose Name Verbose Name Short Name 

As you can see, I am using a totally inappropriate 'skipws' stream modifier flag as a poor man's 1 level verbose flag - that was just to show the in stream approach I was looking for without havnig to add a member object to each of my printable objects (all suggestions for better approaches would be welcome but I would like to minimize the changes to each of my printable objects - as I have quite a lot). Secondly the flag is persistent until reset later - some other stream flags only last for the next stream operator but I am not exactly sure how that works and thirdly

2 Answers 2

3

You can store custom state in your stream instance:

See it Live On Coliru

#include <iostream> static int const index = std::ios_base::xalloc(); std::ostream& verbose(std::ostream& stream) { stream.iword(index) = 1; return stream; } std::ostream& noverbose(std::ostream& stream) { stream.iword(index) = 0; return stream; } struct StructA { std::string mLongName; std::string mShortName; inline friend std::ostream& operator << (std::ostream& os, const StructA& rStruct) { switch (os.iword(index)) { case 1: return os << rStruct.mLongName; case 0: default: return os << rStruct.mShortName; } } }; int main() { StructA a; a.mLongName = "loooooooooooooooooooong names are tedious"; a.mShortName = "succinctness"; std::cout << a << '\n'; std::cout << verbose; std::cout << a << '\n'; std::cout << noverbose; std::cout << a << '\n'; } 

Credits go to Dietmar Kühl's answer.

If you needed siginificant amounts of state/logic, you would have to look at imbue-ing a custom locale facet. His answer shows the basics of this approach too.

Sign up to request clarification or add additional context in comments.

Comments

1

It seems you are in this case too reluctant to create an abstraction for some reason. Don't take this personally I only write this because I once was too hesitant to do that, but create abstractions. Create a Logger class based on iostream either by inheritance or containment which behavior you can modify. Let's say the logger has options like

enum {SHORT,VERBOSE,DEBUG}; 

Let this option be static so that it has application wide effect on all the instances. Really there only needs to be one instance perhaps?

I realize that all your printable objects need to support the various printing options in a consistent way, i.e. all need to have shortName and longName.

4 Comments

@sehe: can you elaborate more on what you mean please.
@sehe: It might still be better to create an abstraction because further down the road in the maintenance it is much more flexible. It is not at all a demeaning claim. It is always a balance whether you should create an abstraction or not. Many considerations might come into play e.g. performance. It is a benefit to have a type rich source as well.
@sehe: I rephrased my formulation. I'm not an English native speaker.
If the abstraction already exists, then adding one more, by definition, is not making it faster. Edit Thanks for re-wording that.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.