The best way to call a function with different arguments passed by reference when you need only one of these arguments

This is a simple question:

If I need to call a method like this, for example:

void getBounds(float &xmin, float &ymin, float &zmin, float &xmax, float &ymax, float &zmax) 

What is the correct way to call a method if I just need the information stored in xmax? I do not want to create variables that I will not use.

Is there any way to do this? Let's say that the wrong way to do what I want would be something like this:

 float xmax; getBounds(nullptr, nullptr, nullptr, xmax, nullptr, nullptr); 

Now I am using dummy-trash variables, but maybe there is another way.

Thanks in advance.

EDIT: Sorry, I forgot to mention that I cannot edit this method from a third-party library.

+4
source share
6 answers

Can you change getBounds or not? If you can and calculate each of the values โ€‹โ€‹expensively, it may be worth changing it to pass the pointers, and only perform the corresponding calculation if the pointer is not equal to zero. Otherwise, you need to pass the lvalue (variable) value for each. And theoretically, if you pass the same variable to more than one argument, you can get undefined behavior in the function (say, because the function starts with something along the lines xmin = ymin = 0.0; ).

Finally, if calculating each value is not expensive, and the function skips it if it receives a null pointer, creating and passing additional variables is unlikely to have any impact on performance.

+2
source

Sort of:

 float dummy; float xmax; getBounds(dummy, dummy, dummy, xmax, dummy, dummy); 

This will create only one variable on the stack, thereby saving space. Creating more of them will not have any side effect, except taking 4 more bytes each [assuming โ€œnormalโ€ size floats, the standard does not specify the exact size of float] - to create one or five (or hundreds) stacks, uninitialized variables, It takes the same amount of time.

Using pointers will allow you to pass nullptr , but will also add extra validation to getBounds , so

 void getBounds(....) { xmin = the_getXmin_function(); ... } 

becomes:

 void getBounds(....) { if (xmin != nullptr) *xmin = the_getXmin_function(); ... } 

Assuming the_getXmin_function trivial, this will slow down the code. If the function is complex, then having an if option and โ€œI don't want thisโ€ will help performance quite a bit.

+1
source

Confirm to Matsu Peterson: you cannot pass nullptr, as the function requires references.

If a function does not have any guarantees for it, then you must create temporary variables and pass them all. It is unsafe to pass the same variable; in case it is used in internal calculations.

Even if a function works with the same passed variable, there is no guarantee that someone will not change the implementation of this function so that your code breaks. In the future, you may open yourself up for unpleasant mistakes.

0
source

You cannot send nullptr if the function expects a link

But if you change your function signature to a pointer, you can go for something like: void getBounds(float *xmax, float *xmin = nullptr, float *ymin = nullptr, float *zmin = nullptr, float *ymax = nullptr, float *zmax = nullptr) { }

and name it: getBounds( &xmax); but then you should check your function if the variable is nullptr or no

but as stated in the comment, it will only work in one case

0
source

If you wrote this method, just change the function signature to

 void getBounds( float*, float*, float*, float*, float*, float* ) 

so you can pass nullptrs if you want to ignore the parameter. Otherwise, you can write a wrapper function.

 void getBounds( float*a, float*b, float*c, float*d, float*e, float*f ) { float dummy; getBounds( a ? *a : dummy, b ? *b : dummy, c ? *c : dummy, d ? *d : dummy, e ? *e : dummy, f ? *f : dummy ); } 

If your situation does not occur regularly, another way of handling this may be to record

 float xmax; // in outer scope { float dummy; // in inner scope. Will be thrown away afterwards getBounds( dummy, dummy, dummy, xmax, dummy, dummy ); } 

so that you do not interfere with you.

I would prefer the first option.

0
source

If you can rewrite getBounds and can use C ++ 11, consider using a tuple, binding and ignoring:

 std::tuple<float, float, float, float, float, float> getBounds() { std::tuple<float, float, float, float, float, float> r; : std::get<3>(r) = ...; : return(r); } : float xmax; std::tie(std::ignore, std::ignore, std::ignore, xmax, std::ignore, std::ignore> = getBounds(); 

- EDIT -

As you cannot change it, you can overload it. The parametric version simply wraps the original, packs everything into a tuple and returns it.

0
source

Source: https://habr.com/ru/post/1487427/


All Articles