tags:

views:

105

answers:

5
+2  A: 

You can also put the call-only-once logic, which you already outlined, inside OtherRoutine, causing it to return early if it has already been executed before.

Logically, its pretty much the same. Stylistically, it might be nicer.

abelenky
And doesn't the standard library / boost have something like `call_function_once` routine? I thought this may be somewhat useful... Anyway, your answer is nice
HardCoder1986
+3  A: 

Take a look at Boost Thread's one-time initialization mechanism

Kristopher Johnson
+2  A: 

You were definitely on the right track already. You should put your static 'called' variable inside your struct... ahem: you should make it a class instead, make it private, and make sure the state of the static variable is queried inside of OtherRoutine. You should not make it more complicated than it needs to be. Using boost, or anything else for so simple a mechanism is just overkill.

C Johnson
+2  A: 

You could achieve this with boost::function and bind. Assuming you want OtherRoutine only to be called once per object,

struct A {
    A() {
        Routine = boost::bind(&A::OtherRoutine, this); 
    }

    boost::function<void()> Routine;

private:
    void MainRoutine() {
        // Do stuff that should occur on every call
    }

    void OtherRoutine() {
        Routine = boost::bind(&A::MainRoutine, this);
        // Do stuff that should only occur once
        MainRoutine();
    }
};

A foo;
foo.Routine(); // OtherRoutine is called
foo.Routine(); // Now all subsequent calls will go to MainRoutine
foo.Routine();

I would suggest doing what the other people have said, though. While this may look 'cleaner,' it's overly complicated when compared to the alternatives.

dauphic
A: 

Another way that verges on "cute" would be to have a static object and call your function from within its constructor. Something like...

   struct OneShotOtherRoutine
   {
      OneShotOtherRoutine(A a, Params params)
      {
         a.OtherRoutine(params);
      }
   };

   struct A
   {
      friend struct OneShotOtherRoutine;
      public:
         void MainRoutine(Params params)
         {
              static OneShotOtherRoutine(params);
              // Main Routine code
         }
      private:
         void OtherRoutine(Params params)
         {
           // Other routine code
         }
  };

You'd have to split things up so that each implementation could see the other struct's declaration, but this could do what you want, assuming it's acceptable that OtherRoutine gets called when statics are initialized.

JohnMcG