Reputation: 243
I know it's possible to do something like :
int foo(int a = 0, int b = 1) { return a + b; }
and then use it without the default parameters eg.:
foo(); // a = 0, b = 1 -> 1
or with the last one as default eg.:
foo(2); // a = 2 and b = 1 default -> 3
But my question is: Is it possible to use the default value for the first argument (a) and give the value of the second (b)
My first thought was doing it like (which doesn't work!):
foo(,2); // a = 0 default and b = 2
Does a syntax for this exist or is this just not possible ?
Upvotes: 23
Views: 12675
Reputation: 1
no it is not possible first parameter has to be filled by some value
Upvotes: -2
Reputation: 739
Though still not possible the way OP expects, there is since c++17 a way to mimic this behaviour using std::optional
.
Instead of passing int
as arguments, pass optional<int>
with default value of {}
:
int foo(std::optional<int> in_a = {}, std::optional<int> in_b = {});
Then replace in the function body by the "real" default values if the user did not provide a value ({}
or std::nullopt
was passed):
int foo(std::optional<int> in_a = {}, std::optional<int> in_b = {})
{
const auto a = in_a.value_or(default_value_for_a);
const auto b = in_b.value_or(default_value_for_b);
return a + b;
}
For example, assuming you want default value of a
but not b
, you now do:
foo({}, value_for_b);
This generalises well when more parameters are added. The only restriction is that you must be able to put the type in optional
, which has some restrictions regarding this.
Upvotes: 2
Reputation: 123431
It is not possible directly. However, it is possible somehow if you declare a struct for the input parameters that encapsulates the default values and has individual setters:
#include <iostream>
struct Foo{
int a,b;
Foo() : a(0),b(1) {};
Foo setA(int x) { a=x; return *this;}
Foo setB(int x) { b=x; return *this;}
};
void foo(Foo f = Foo()){ std::cout << f.a << " " << f.b << std::endl; }
int main() {
foo(); // uses default values for a and b
foo(Foo().setA(3)); // uses default value for b
foo(Foo().setB(5)); // uses default value for a
}
Upvotes: 1
Reputation: 19
Once we provide a default value for a parameter, all subsequent parameters must also have default values. For example,
// Invalid
void add(int a, int b = 3, int c, int d);
// Invalid
void add(int a, int b = 3, int c, int d = 4);
// Valid
void add(int a, int c, int b = 3, int d = 4);
Upvotes: 1
Reputation: 1
Alternatively from specifying default parameter values you can use multiple function overloads like:
int foo(int a, int b){return a+b; }
int foo(int b){return foo(0,b); }
int foo(){return foo(0,1); }
Upvotes: 8
Reputation: 752
I know that it is not really an answer to your question, but you could try to use boost named parameters. It might be useful for your use case.
Upvotes: 0