Tutorial :c++ #define a macro with brackets?



Question:

Instead of doing the following everytime

start();    // some code here    stop();  

I would like to define some sort of macro which makes it possible to write like:

startstop()  {    //code here    }  

Is it possible in C++?


Solution:1

You can do something very close using a small C++ helper class.

class StartStopper {  public:      StartStopper() { start(); }      ~StartStopper() { stop(); }  };  

Then in your code:

{      StartStopper ss;      // code here  }  

When execution enters the block and constructs the ss variable, the start() function will be called. When execution leaves the block, the StartStopper destructor will be automatically called and will then call stop().


Solution:2

The idiomatic way of doing this in C++ is called Resource Acquisition Is Initialization, or shortly RAII. In addition to providing what you want, it also has the added benefit of being exception safe: the stop function will be called even if your code throws an exception.

Define a guard struct:

struct startstop_guard  {      startstop_guard()      {          start();      }      ~startstop_guard()      {          stop();      }  };  

and then rewrite your code this way:

{      startstop_guard g;      // your code  }  

The guard's destructor (and thus the stop function) will be called automatically at the end of the enclosing block.


Solution:3

Other answers have addressed the RAII side of the question well, so I'm going to address the syntax side of it.

#define startstop for(Starter s; s.loop; s.loop = false)  struct Starter {      bool loop;      Starter() { start(); loop = true; }      ~Starter() { stop(); }  };  

Used like:

startstop {      // some code  }  

Should be self-explanatory enough.


Solution:4

#define startstop(x, y, ...) for( /* use macro args */ )  


Solution:5

Generic solution with RAII and boost::function ( std::function ).

class starter  {      typedef boost::function< void () > action;      action end_;  public:      starter(action start, action end):          end_(end)      {           log("starter start");          start();       }      ~starter()      {           log("starter end");          end_() ;       }  };  int main()  {      {          starter s(start, stop);          middle();      }        return 0;  }  

or to test and check the idea

    void print(const std::string& message)      {          std::cout << message << std::endl;      }      int main()      {          starter s(boost::bind(print, "globalstart"),                    boost::bind(print, "globalend"));             {              starter s(boost::bind(print, "start"),                        boost::bind(print, "end"));               std::cout << "middle" << std::endl;          }          return 0;      }  


Solution:6

What are you trying to do? I'd recommend checking out RAII as a much more C++ oriented way of doing things than macro hacking, with all its unforeseen consequences.


Solution:7

Don't use macros. You can use inline functions instead as it provides type checking and other features. You can take a look here: inline functions


Solution:8

credit to dirkgently for the idea.. I thought I'd fill the rest in

#define startstop() for(start();isStarted();stop())


Solution:9

In c#, you could use the IDisposable pattern, and implement your Stop() functionality in the Dispose() method, but that would would work if you were using a .net variant of c++.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »