[Qt-interest] Semi-OT: indentation with operator<<

K. Frank kfrank29.c at gmail.com
Mon Aug 2 02:14:26 CEST 2010


Hello Andre -

Thanks for your refinement.

On Wed, Jul 28, 2010 at 2:48 PM, Andre Somers <andre at familiesomers.nl> wrote:
> ...
> If you want, you could wrap it up into a RAII class, so you can not
> forget about it and early exits and the likes are automatically handled.
> That might make it slightly cleaner to work with, perhaps. The RAII
> class would basically look like this:
>
> class Indenter
> {
>     public:
>     Indenter() {++indentation_level;}
>     ~Indenter() {--indentation_level;}
>     int level() {return indentation_level;}
> }
>
> indentation_level can be a global variable, or a static member variable
> of Indenter. Preferably the latter.
> You can then use it in your output by simply creating an instance on the
> stack and reading the level when you need it. Since you created it on
> the stack, the destructor will be called as soon as it goes out of scope.
>
> *That* would IMHO be the C++ way to do it. No hassle with singletons
> needed. At around 10 of these indentation-needing POD's, you have less
> code already, since you loose all those manual decreasements of the
> indentation variable. And you will have less issues with a forgotten
> decreasing somewhere. Sooner or later you, or the one maintaining and
> expanding your code, will.

I think I follow what you are saying.  To make it concrete, let
me add the static variable you mention and refer back to my
example:

class Indenter {
  public:
    Indenter() {++indentation_level;}
    ~Indenter() {--indentation_level;}
    static int level() {return indentation_level;}
    static int indentation_level = 0;
}

class MoreStuff {
 // ...
 friend std::ostream& operator<< (std::ostream& o, MoreStuff const& m);
};

// Indenter-based implementation

std::ostream& operator<< (std::ostream& o, MoreStuff const& m) {
  for (unsigned i = 0; i < Indenter::level(); i++)  o << ' ';
  o  <<  "double1_   =  "  << m.double1_  <<  "\n";
  for (unsigned i = 0; i < Indenter::level(); i++)  o << ' ';
  o  <<  "point3d_   =  "  << m.point3d_  <<  "\n";
  for (unsigned i = 0; i < indent_depth; i++)  o << ' ';
  o << "someStuff_ = ...\n";
  {   <-- braces to define scope of RAII Indenter
    Indenter i;   <-- constructor increments indentation_level
    o << someStuff_;
  }   <-- closing brace: destructor decrements indentation_level
  return o;
}

// original implementation for comparison

std::ostream& operator<< (std::ostream& o, MoreStuff const& m) {
  for (unsigned i = 0; i < indent_depth; i++)  o << ' ';
  o  <<  "double1_   =  "  << m.double1_  <<  "\n";
  for (unsigned i = 0; i < indent_depth; i++)  o << ' ';
  o  <<  "point3d_   =  "  << m.point3d_  <<  "\n";
  for (unsigned i = 0; i < indent_depth; i++)  o << ' ';
  o << "someStuff_ = ...\n";
  indent_depth += 2;
  o << someStuff_;
  indent_depth -= 2;
  return o;
}

> André

Makes sense to me.

Best.


K. Frank




More information about the Qt-interest-old mailing list