0

I use a monitoring class Progress. In a lot of functions, I update the progress if given. The progress variable is optional and given by pointer that could be null. A lot of part of my code look like this:

void do_the_job(Progress* progress)
{
  do_part_1();
  if((bool)progress)
    progress->set(0.25f);
  do_part_2();
  if((bool)progress)
    progress->set(1.0f);
}

Before creating it myself, I'm looking for a kind of smart pointer checking for me if it's null and ignoring the call if null. Somthing that could be used like this:

void do_the_job(boost::could_be_null_ptr<Progress> progress)
{
  do_part_1();
  progress->set(0.25f); // ignored if null
  do_part_2();
  progress->set(1.0f); // ignored if null
}

For compatibility reason, I don't use C++11 or >C++11. Please, only solutions working with C++03.

Caduchon
  • 4,574
  • 4
  • 26
  • 67
  • 4
    There's certainly no reason to check it more than once in a function. You could just have, at the start of the function, `if (!progress) return;`. Another option might for the context in which all these functions are called to ensure that it does not pass a null, depending upon how that part of your code is designed. – lurker Jun 30 '20 at 14:53
  • 2
    can't you use conditions? – anastaciu Jun 30 '20 at 14:53
  • Does this answer your question? [Is there a safe navigation operator for C++?](https://stackoverflow.com/questions/45149760/is-there-a-safe-navigation-operator-for-c) or https://stackoverflow.com/questions/1785426/c-sharp-null-coalescing-operator-equivalent-for-c or many more. Spoiler: no, this can't be done, and it can't be coded in a library either, not even in a modern version of C++. – underscore_d Jun 30 '20 at 14:54
  • 3
    `if((bool)progress)` is pointlessly verbose, just do `if(progress)`. – Jesper Juhl Jun 30 '20 at 14:56
  • @lurker the progress is only a monitoring tool. (for example for a progress bar). If the pointer is null, the function must do the job, just ignore the update of the progress object. – Caduchon Jun 30 '20 at 14:56
  • Use a null object ie an instance of `Progress` that doesn't do anything. Then `do_the_job` doesn't need to check whether `progress` is null. – Jack Hughes Jun 30 '20 at 14:58
  • @underscore_d: I asked for a C++03 answer, you link to a C++17 question. – Caduchon Jun 30 '20 at 15:01
  • @Caduchon ...wherein they say this still isn't (as written, without unbearable verbosity) possible in C++17, so of course it wasn't possible in C++03. Do you get it yet? – underscore_d Jun 30 '20 at 15:01
  • In that case, you should have a look at the posted answer. It puts the responsibility on the object (struct) itself to handle the case where there is no instance rather than to put that burden on every case where you attempt to use it. – lurker Jun 30 '20 at 15:06
  • @JackHughes: it simplifies the content of the function `do_the_job` but not the call when the user doesn't use the progress (example: `do_the_job(0);` is easy to call) – Caduchon Jun 30 '20 at 15:10

1 Answers1

2

The function should not have to bother with a null pointer so design the Progress such that it can be used like this:

void do_the_job(XProgress& progress)
{
  do_part_1();
  progress.set(0.25f);
  do_part_2();
  progress.set(1.0f);
}

Getting there is simple:

struct XProgress {
   std::shared_ptr<Progress> instance;
   void set(float x) {
       if (instance) instance->set(x);
   }
};

In any case you need some instance on which you can call set, so there is no way to avoid reimplementing Progesss interface.

Sorry, missed the "only C++03". If you cannot use shared_ptr use the memory mangagment mechanism of your chioce. Perhaps a raw pointer that gets deleted in XProgress destructor is fine if you disable copying.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185