0

Assume this code:

#include<stdio.h>    

int t(int a, int b=6, int c=7){
 return b;
}

int main(){    
  
  return 0;  
} 

How can I call t and only pass a and c values and let b as the default value?

Dan
  • 577
  • 1
  • 3
  • 9
  • 4
    That's not possible in c++ currently. If you provide an argument, all the preceding arguments must be provided as well. – cigien Jul 20 '20 at 14:00
  • 4
    Does this answer your question? [Default argument in the middle of parameter list?](https://stackoverflow.com/questions/5637679/default-argument-in-the-middle-of-parameter-list) – Aplet123 Jul 20 '20 at 14:01
  • 1
    @Aplet123 That question is talking about declarations of functions, not calls. – cigien Jul 20 '20 at 14:02
  • 3
    How do you plan on using this? e.g. If you write `t(1,2);` which version are you calling? The one with `b` defaulted, or `c`? – cigien Jul 20 '20 at 14:11

2 Answers2

3

There is no way to do that. Arguments can only be passed in order, and therefore it is not possible to use a default argument for an argument that is before another that is passed explicitly.

You could however use an aggregate class as an argument, which combined with default member initialisers and designated initialisers (C++20) is a decent emulation of named argument passing:

struct Args {
    int a;
    int b = 6
    int c = 7;
};

int t(const Args& args);

int main()
{
    t({
        .a = 42,
        // b will be 6
        .c = 1337,
    });
}

Using designated initialiser isn't mandatory, so C++20 isn't required. It's just more concise and readable.

Depending on the structure of the program, it may make sense for t to be a member function of the class.

eerorika
  • 232,697
  • 12
  • 197
  • 326
2

This will work if you just want to overload b. If you aim at overloading c at the same time, then you should go with something more complex as mentioned in other answers. ;)

There is no direct way to do that in C++. Though you can chain function calls (this is very popularly used in implementing methods of classes with members as default params).

Something like this should work just fine as a workaround:

#include<iostream>    

int t(int a, int b, int c) {
  return b;
}

int t(int a, int c) {
  return t(a, 6, c);
}

int main() {    
  auto x = t(1, 2); // this will call t with a = 1, b = 6, c = 2
  std::cout << x;   // prints 6
  return 0;  
} 
brc-dd
  • 10,788
  • 3
  • 47
  • 67
  • What happens when you want `c` to be the default parameter? – cigien Jul 20 '20 at 14:14
  • @cigien It simply won't work in that case. eerorika's answer is better, though it didn't first hit me. :) – brc-dd Jul 20 '20 at 14:16
  • 1
    Yes. So this answer doesn't really answer the question. – cigien Jul 20 '20 at 14:17
  • 2
    @cigien The question is _How can I call `t` and only pass `a` and `c` values and let `b` as the default value?_ My way does exactly that, though I can't extend if he want to overload both `b` and `c`... Well, the OP hasn't mentioned that requirement in his question for now. – brc-dd Jul 20 '20 at 14:19
  • 1
    Yes, technically the OP hasn't said they need that :) – cigien Jul 20 '20 at 14:23