Why are default arguments in C++ trailing ones?
4 Answers
if you had void func(int a = 0, int b);, how would you specify to use the default parameter in calling this function?
7 Comments
func(,some_val_for_b), or named parameters.Looks ugly has never been a design criteria of C++.b (because where else would it go?) and if you pass two arguments, the first one gets bound to a and the second one gets bound to b, because, again, nothing else makes sense. There's no ambiguity there. A list is symmetric, after all, it looks and works the same from either side. So, if you believe that putting default arguments at the end of the argument list is okay, and since lists are symmetric, you logically have to accept the fact that putting them at the beginning works just as well.Because that is how the language has been designed.
A more interesting question would be: what are the alternatives?
Suppose you have void f(A a = MyA, B b);
- Placeholder / blank argument:
f(_, abee)orf(, abee) - Named arguments (like in Python):
f(b = abee)
But those are niceties and certainly not necessary, because unlike Python C++ supports function overloading:
void f(A a, B b);void f(B b) { f(MyA, b); }
and thus the default arguments are unnecessary... especially considering that there are issues when used with polymorphic code because default arguments are statically resolved (compile-time).
struct Base
{
virtual void func(int g = 3);
};
struct Derived
{
virtual void func(int g = 4);
};
int main(int argc, char* argv[])
{
Derived d;
d.func(); // Derived::func invoked with g == 4
Base& b = d;
b.func(); // Derived::func invoked with g == 3 (AH !!)
}
Regarding named parameters:
The feature can be emulated using function objects.
class Func
{
public:
Func(B b): mA(MyA), mB(b) {}
A& a(A a) { mA = a; }
B& b(B b) { mB = b; }
void operator()() { func(mA, mB); }
private:
A mA;
B mB;
};
int main(int argc, char* argv[])
{
A a;
B b;
Func(b)();
Func(b).a(a)();
}
In case you don't want to copy the arguments, you have the possibility to use references/pointers though it can get complicated.
It's a handy idiom when you have a whole lot of defaults with no real order of priority.
2 Comments
func prototype it's clear that if there is only one parameter then the default value should be used for the first parameter, whatever their type. Things get hairy when you have two default though ;) In general, named parameters are the only thing that may solved the issue, and what's great is that they are a compile-time solution.func(A a, B b), func(B b) and func(A a).Just to supplement @tenfour's answer. C++ FAQ Lite has a topic describing named parameters and I think the topic addresses your issue to some extent.
Comments
Because in a function call you have to call the non-default arguments in any case. If you put your default argument at the beginning of the argument list, how are you supposed to say you are setting the default argument or the other ones?
9 Comments
b on?