12

Why are default arguments in C++ trailing ones?

1
  • 1
    The answer you selected doesn't answer your question at all. Commented Jun 1, 2015 at 14:34

4 Answers 4

16

if you had void func(int a = 0, int b);, how would you specify to use the default parameter in calling this function?

Sign up to request clarification or add additional context in comments.

7 Comments

I know you can't in C++, but other languages handle this with func(,some_val_for_b), or named parameters.
@Dominic Rodger: to me that looks really ugly.
@Dominic Rodger, well, C++ doesn't. If you want you can sue Stroupstroup :P
Looks ugly has never been a design criteria of C++.
What's the problem? If you pass one argument, it clearly gets bound to 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.
|
7

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) or f(, 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

@Oli: why ? given the first 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.
Yes, you are right. I thought you were using overloading to disambiguate func(A a, B b), func(B b) and func(A a).
1

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

-1

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

What is it that makes the beginning of a list so fundamentelly different from the end of the list? Lists are symmetrical!
Yes, but imagine this: void func(int a, int b=0, int c, int d=0); What are you doing when you call func (1, 2, 3);
And which end of the list, exactly, is b on?
The 'end onf the list' issue was just an example
@JW Mittag "lists are symmetrical" - you mean, like a singly-linked list, where navigation is one-way ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.