Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One line solution for unused out parameter reference

I use a function which use 2 reference parameters to return values, only one of this value interess me. Is there a proper way to do it in one line.

I'll explain myself with the code

Function code

void Limits (double& min, double &max)
{
    min = MIN;
    max = MAX;
}

using the function

double min;
double unused;

Limits(min, unused);

// using myDouble but not unused

What i would like to write is something like

double min;

Limits(min, double());

I can't find a way without previously properly declare the object. Is there an elegant solution?

I can't modify the function.

like image 709
Giacogiac Avatar asked Nov 18 '14 16:11

Giacogiac


People also ask

What are out mode parameters?

An out-parameter represents information that is passed from the function back to its caller. The function accomplishes that by storing a value into that parameter. Use call by reference or call by pointer for an out-parameter.

What is the use of out parameter in C#?

The out parameter in C# is used to pass arguments to methods by reference. It differs from the ref keyword in that it does not require parameter variables to be initialized before they are passed to a method. The out keyword must be explicitly declared in the method's definition​ as well as in the calling method.

Do you need to declare out variable before you use it?

Variables passed as out arguments do not have to be initialized before being passed in a method call. However, the called method is required to assign a value before the method returns.


3 Answers

I think, with C++11 and its rvalue references, you can implement the requested one-liner. It reads as follows:

template<class T> T& make_dummy_out(T&& t) { return t; }

Then you can call your Limit function as follows:

double min;
Limits(min, make_dummy_out(double()));

This is safe, because the lifetime of the ad-hoc-created double() will be until the end of the statement, which is after the Limits() call has been completed.

Note, that make_dummy_out() is basically the opposite of std::move(): While std::move() turns an lvalue reference explicitely into an rvalue reference, make_dummy_out() converts an rvalue reference explicitely into an lvalue reference. Of course, you need to declare the template function only once, and then can use it to create dummy output parameters whereever you need it.

like image 186
Kai Petzke Avatar answered Oct 11 '22 13:10

Kai Petzke


I'm not sure why having to declare an additional variable is a problem. Regardless, if you can't modify the function, make a wrapper:

void MyLimits(double& min) {
  double unused;
  Limits(min, unused);
}

Or you could do something funky like this:

double min;

Limits(min, *std::unique_ptr<double>(new double));
like image 37
glank Avatar answered Oct 11 '22 12:10

glank


The most obvious solution would be to use pointers:

void
Limits( double* min, double* max )
{
    if ( min != nullptr ) {
        *min = myMin;
    }
    if ( max != nullptr ) {
        *max = myMax;
    }
}

//  ...
double min;
Limits( &min, nullptr );

Alternatively, you could just define separate functions:

void Limits( double& min, double& max );
void UpperLimit( double& max );
void LowerLimit( double& min );

EDIT:

Since the orginal poster has since indicated that he cannot modify the function, he should wrap it with one which uses pointers:

void myLimits( double* min, double* max )
{
    double ignore;
    Limits( min == nullptr ? ignore : *min,
            max == nullptr ? ignore : *max );
}
like image 20
James Kanze Avatar answered Oct 11 '22 12:10

James Kanze