Question

Suppose i have a function that returns an important result and several unimportant results. I declared it so that the unimportant results are returned by reference:

int CalculateStuff(int param1, int param2, int& result1, int& result2);

I would like to call this function to calculate some stuff, but at call site i want to ignore the unimportant results. I could do it as follows:

...
int dummy1, dummy2;
int result = CalculateStuff(100, 42, dummy1, dummy2);
... // do something with the result

I would like to consider another way to do the same without declaring dummy variables:

int result = CalculateStuff(100, 42, *new int, *new int);

This has a memory leak (unacceptable), but has an advantage of showing my intent (ignoring the results) more clearly than the "dummy" names.

So, what would happen if i wrote it as follows:

int result = CalculateStuff(100, 42, auto_ptr(new int).get(), auto_ptr(new int).get());

Is it legal? Will the temporary integers still exist when the function's code is executed? Should i use unique_ptr instead of auto_ptr?

(Please don't suggest refactoring my code; i probably will - but first i want to understand how this stuff works)

Was it helpful?

Solution

It is legal; auto_ptr objects will remain alive until the end of expression (i.e. function call). But it is ugly as hell.

Just overload your function:

int CalculateStuff(int param1, int param2, int& result1, int& result2);
int CalculateStuff(int param1, int param2) { 
    int r1=0, r2=0; 
    return CalculateStuff(param1, param2, r1, r2);
}

OTHER TIPS

According to Bjarne Stroustrup, if some parameters are optional, it is an ideal case for making them pointer type, so that you can pass NULL when you don't need to pass arguments for them:

int CalculateStuff(int param1, int param2, int * result1, int * result2);

And use:

int result = CalculateStuff(100, 42, NULL, NULL);

All other alternatives would not be as good as this one, or at least not better than this.

Of course, the implementation of CalculateStuff has to check the parameters if they're NULL or not.

Here is my advice: if you have to ask on SO to figure out the correctness of the code and its semantics, then the code fails at clearly expressing your intent.

I think the first version (with dummy1 and dummy2) is the most transparent, and is obviously correct.

If you find yourself repeatedly calling the function and not wanting the optional results, you could provide an overload:

int CalculateStuff(int param1, int param2, int& result1, int& result2) {}

int CalculateStuff(int param1, int param2) {
  int unwanted1, unwanted2;
  return CalculateStuff(param1, param2, unwanted1, unwanted2);
}

A recommended approach if you have control over the function would be: return a std::tuple (or boost::tuple) with all results or write an overload that doesn't need the extra variables.

You could make a class that provides implicit (or explicit) conversion to int&.

struct ignored
{
   int n;
   operator int&() { return n; }
};

n = CalculateStuff(a, b, ignored(), ignored());

You can further make this a template and add const overloads.

It's legal, but it's not guaranteed not to leak memory, see question 3 here for example.

The correct and idiomatic way of implementing optional output is to pass a pointer, passing NULL when you don't want the results, and testing for NULL in the function before writing through the pointer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top