3

Is there a compact way of skipping an out-parameter from a function call by passing some dummy?

In the example below I would like to write something like calc_multiples(myNum, NULL, myNumTimes3), because I do not need the second parameter and hence do not want to define a variable for that.

In python one would use _ for that..

#include <iostream>


/**                                                                                        
 * Calculates multiples of number
 *                                                                                         
 * @param[in] t1 number to multiply                           
 * @param[out] t2 multiplied by 2
 * @param[out] t2 multiplied by 3
 */
void calc_multiples(const int t1, int &t2, int &t3)
{
    t2 = 2*t1;
    t3 = 3*t1;
    return;
}

int main()
{
    int myNum = 7;
    int myNumTimes2; // I want to avoid this line
    int myNumTimes3;
    
    calc_multiples(myNum, myNumTimes2, myNumTimes3);
    
    std::cout << "my number times 3: " << myNumTimes3;
    
    return 0;
}
Markus Dutschke
  • 9,341
  • 4
  • 63
  • 58
  • 1
    Reference has to refer to a valid object of the specified type, so unless you have a valid object lying around that you can use as a throw-away junk receptacle, you're out of luck. Have you considered returning a structure like `std::pair` instead of multiple output parameters? – user4581301 Aug 27 '21 at 17:08
  • Regarding the edit: if `t3` is not optional, it should be a reference rather than a pointer. – HolyBlackCat Aug 27 '21 at 17:33
  • @HolyBlackCat: I guess the reason to prefer a reference over a pointer for `t3` is that you can break less, right? https://www.geeksforgeeks.org/passing-by-pointer-vs-passing-by-reference-in-c/ – Markus Dutschke Aug 27 '21 at 17:45
  • 1
    @MarkusDutschke Unsure what you mean by "break less". References can't be null (legally), so by using one you're clearly signalling that the parameter is not optional, and you don't need to check if you got a null or not. – HolyBlackCat Aug 27 '21 at 17:47
  • 1
    Please move the answer from the question to an answer. A question should contain the question, the whole question, and nothing but the question. – user4581301 Aug 27 '21 at 20:53
  • @user4581301 I fully agree about the issue. The reason I did it, is that I did not want to modify HolyBlackCats answer (because I consider it as rude), did not want to copy it by writing an answer on my own (because credit belongs to HolyBlackCat) and never the less wanted to give a copy-paste solution. Are there any stackoverflow guidlines concerning this? I am happy to fix this till monday – Markus Dutschke Aug 28 '21 at 05:44
  • In the future it's probably better to post a separate answer to show the code you ended up with, rather than edit the question or one of the existing answers. – HolyBlackCat Sep 01 '21 at 18:24

2 Answers2

3

You can simply define another function that omits the undesired parameter:

#include <iostream>

/**                                                                                        
 * Calculates multiples of number
 *                                                                                         
 * @param[in] t1 number to multiply                           
 * @param[out] t2 multiplied by 2
 * @param[out] t2 multiplied by 3
 */
void calc_multiples(const int t1, int &t2, int &t3)
{
    t2 = 2*t1;
    t3 = 3*t1;
    return;
}

void calc_multipleOf3(const int t1, int &t3)
{
    int ignored;
    calc_multiples(t1, ignored, t3);
}

int main()
{
    int myNum = 7;
    int myNumTimes3;
    
    calc_multipleOf3(myNum, myNumTimes3)
    std::cout << "my number times 3: " << myNumTimes3;

    return 0;
}

Alternatively:

#include <iostream>

/**                                                                                        
 * Calculates multiples of number
 *                                                                                         
 * @param[in] t1 number to multiply                           
 * @param[out] t2 multiplied by 2
 * @param[out] t2 multiplied by 3
 */
void calc_multiples(const int t1, int &t2, int &t3)
{
    t2 = 2*t1;
    t3 = 3*t1;
    return;
}

int main()
{
    int myNum = 7;
    int myNumTimes3;
    
    auto calc_multipleOf3 = [](const int t1, int &t3) {
        int ignored;
        calc_multiples(t1, ignored, t3);
    };

    calc_multipleOf3(myNum, myNumTimes3)
    std::cout << "my number times 3: " << myNumTimes3;

    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
1

There's no direct alternative to Python's _.

The function should be rewritten to take pointers instead of references, and it should check that the pointers are not null before writing to them.

Then you would pass nullptr to the parameters you want to skip.

Comment by the author of the question (Markus Dutschke)

Code would look like this

#include <iostream>

/**                                                                                        
 * Calculates multiples of number
 * 
 * THIS IS JUST FOR DEMONSTRATION.
 * OF COURSE ONE WOULD USE DEFAULT ARGUMENTS IN THIS CASE.
 *                                                                                         
 * @param[in] t1 number to multiply                           
 * @param[out] t1 multiplied by 2 (optional argument)
 * @param[out] t1 multiplied by 3 (mandatory argument)
 */
void calc_multiples(const int t1, int *t2, int &t3)
{
    if (t2 != nullptr)
    {
        *t2 = 2 * t1;
    }
    t3 = 3 * t1;
    return;
}

int main()
{
    int myNum = 7;
    int myNumTimes2; // I want to avoid this line
    int myNumTimes3;
    
    calc_multiples(myNum, nullptr, myNumTimes3);
    
    std::cout << "my number times 3: " << myNumTimes3;
    
    return 0;
}
Markus Dutschke
  • 9,341
  • 4
  • 63
  • 58
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207