7.7 — Default arguments

A default argument is an default value provided for a function parameter. If the user does not supply an explicit argument for a parameter with a default argument, the default value will be used. If the user does supply an argument for the parameter, the user-supplied argument is used.

Because the user can choose whether to supply a specific argument value, or use the default, a parameter with a default value provided is often called an optional parameter.

Consider the following program:

This program produces the following output:

x: 1
y: 10
x: 3
y: 4

In the first function call, the caller did not supply an argument for y, so the function used the default value of 10. In the second call, the caller did supply a value for y, so the user-supplied value was used.

Default arguments are an excellent option when the function needs a value that the user may or may not want to override. For example, here are a few function prototypes for which default arguments might be commonly used:

Multiple default arguments

A function can have multiple default arguments:

Given the following function calls:

The following output is produced:

Values: 1 2 3
Values: 1 2 30
Values: 1 20 30
Values: 10 20 30

Note that it is impossible to supply an argument for parameter z without also supplying arguments for parameters x and y. This is because C++ does not support a function call syntax such as printValues(,,3). This has two major consequences:

1) All default arguments must be for the rightmost parameters. The following is not allowed:

2) If more than one default argument exists, the leftmost default argument should be the one most likely to be explicitly set by the user.

Default arguments can only be declared once

Once declared, a default argument can not be redeclared. That means for a function with a forward declaration and a function definition, the default argument can be declared in either the forward declaration or the function definition, but not both.

Best practice is to declare the default argument in the forward declaration and not in the function definition, as the forward declaration is more likely to be seen by other files (particularly if it’s in a header file).

in foo.h:

in main.cpp:

Note that in the above example, we’re able to use the default argument for function printValues() because the main.cpp #includes foo.h, which has the forward declaration that defines the default argument.

Rule: If the function has a forward declaration, put the default argument there. Otherwise, put them in the function definition.

Default arguments and function overloading

Functions with default arguments may be overloaded. For example, the following is allowed:

If the user were to call print(), it would resolve to print(' '), which would print a space.

However, it is important to note that optional parameters do NOT count towards the parameters that make the function unique. Consequently, the following is not allowed:

If the caller were to call printValues(10), the compiler would not be able to disambiguate whether the user wanted printValues(int) or printValues(int, 20) with the default value.


Default arguments provide a useful mechanism to specify parameters that the user may optionally provide values for. They are frequently used in C++, and you’ll see them a lot in future lessons.

7.8 -- Function Pointers
7.6 -- Function overloading

45 comments to 7.7 — Default arguments

  • Zha Weihua

    Default arguments can only be declared once

    Once declared, a default argument can not be redeclared. That means for a function with a forward declaration and a function definition, the default argument can be declared in either the forward declaration or the function definition, but not both.

    About this conclusion, I saw an inverse example. May I think it's a C++ defect and we should avoid to use it?

    refer to

    #include <iostream>

    void foo(int a, int b, int c = -1)
        std::cout << "foo(" << a << ", " << b << ", " << c << ")\n";

    int main()
        foo(1, 2);   // output: foo(1, 2, -1)

        // error: does not use default from surrounding scope
        //void foo(int a, int b = 0, int c);

        void foo(int a, int b, int c = 30);
        foo(1, 2);   // output: foo(1, 2, 30)

        // error: we cannot redefine the argument in the same scope
        // void foo(int a, int b, int c = 35);

        // has a default argument for c from a previous declaration
        void foo(int a, int b = 20, int c);
        foo(1);      // output: foo(1, 20, 30)

        void foo(int a = 10, int b, int c);
        foo();       // output: foo(10, 20, 30)

            // in inner scopes we can completely redefine them
            void foo(int a, int b = 4, int c = 8);
            foo(2);  // output: foo(2, 4, 8)

        return 0;

    • Hi!

      This is not a defect, it's explicitly allowed.
      "[...] default arguments can be added in later declarations of a function in the same scope."

      I agree, this should be avoided as it requires a reader to read the preceding code to understand a function call (As opposed to reading a single declaration).

  • Hi Alex!

    They're called default arguments, not parameters.

  • magaji::hussaini

    Hi alex I think a note should added that only copy initialisation work with default parameters because I got a compile time error when I tried uniform/direct initialisations.

  • ST.James

    In the challenge section in lesson 6 (the blackjack game), we're almost sure that each time we call shuffleDeck, we will be passing in a deck of cards (&deck); how do we make "&deck" a default parameter?

  • Peter Baum

    1. Is there any good reason why C++ does not support more flexible default values such as



    2. It seems strange that “Once declared, a default parameter can not be redeclared.” even when the declarations are exactly the same.  Is there any good reason why this is not allowed?

    3. In the function overload example:

    the statement is made that “… the compiler would not be able to disambiguate…” such a situation.  Note that it could easily do this if the requirement is to write

    if the second function were desired.

    • nascardriver

      Hi Peter!

      1. I don't think there is. The boost library has a feature to explicitly use a default parameter when calling a function. I like your first suggestions, but I don't like the second one.

      2. Either you declare the parameter with the same default value twice, which is redundant, or you declare them with different default values, which doesn't make sense.

      • Peter Baum

        Hi nascardriver,
        Regarding 2... if they had different default values maybe the compiler could point out the conflict.  That would take care of the redundancy too, because the programmer could use that feature to verify that the code for each section was consistent.

        Not a big deal in any case.


    • Alex

      This is a pretty common question. There's some conversation about this topic here.

      I think the short is that they could have, but it would have made the language more complex, and they didn't feel that was worth the tradeoffs.

      I do wonder if you could work around this by using std::optional, which was introduced in C++17.

      • nascardriver

        @std::optional can be used, but you'd have to set the default value in the function body which isn't where default values should be located in my opinion.
        If there is a better way I'd love to know it.

        Waldo is wearing a red shirt and is located at 12.3, 45.6
        Waldo is wearing a blue shirt and is located at 78.9, 1.2

        • Alex

          I agree. I'm not aware of a way to solve this, but I'm also not that familiar with some of the C++17 stuff, so maybe someone who is knows of a good way to resolve.

  • jayu

    char name[10];

    //I want to enter default value of name like "name= jayu"how I can do that please send me syntax of

  • Trevor

    I should probably try it, but I would think that if a function has default arguments and is called from a different CPP file, then the default values would need to be in the function prototype. My thinking is that the default values are inserted by the compiler as it compiles the calling code, otherwise the linker would need to differentiate between calls with all the arguments and calls with missing arguments which require the default parameters.
    This would raise the interesting (and scary) prospect of being able to define different default parameter values in different CPP files by using different function prototypes for the same function! However I would not recommend using this - just include the required argument value in the call.

    • Alex

      I believe you are correct. This is generally avoided by putting your function prototypes in a header and #including that header wherever you need access to the function. That way you only have a single function prototype.

  • Is there an explicit way to use the default value?
    e.g printValues(-1, *, -1) where '*' means that I would like to use the default value.
    Values: -1 20 -1

  • Nakamura

    How does it work for map? I have a map "std::map<int,std::string> map" , how will it work for optional parameter ?

    • nascardriver

      Hi Nakamura!
      An std::map can be initialized with empty curly braces


  • nikos-13

    "void printStringInColor(std::string, Color color=COLOR_BLACK); // Color is an enum"
    You forgot the parameter's, of type std::string, name.

  • "Note that it is impossible to supply a user-defined value for z without also supplying a value for x and y."
    This function refers to printValues(int x, int y, int z) so I think the sentence should be:
    "Note that it is impossible to supply a user-defined value for x without also supplying a value for y and z."
    Thanks as always.

    • Alex

      Lesson fixed. Thanks!

      • Kess

        Actually, I believe it was correct in it's former version, as in order to provide the value only for x you could just write printValues(3);
        and the function would be called with 3, 20 and 30 as its arguments (20 and 30 being the default values for y and z)

        "Note that it is impossible to supply a user-defined value for x without also supplying a value for y and z."
        Would mean that I would have to write printValues(3, 20, 30); While possible, it's easier and still correct to write printValues(3);

        "Note that it is impossible to supply a user-defined value for z without also supplying a value for x and y."
        Would mean that I cannot write printValues(,,3); which is the intended outcome of that particular part of the lesson. Also, the next sentence in the explanation makes it clear that the intention was to point out that you cannot set z while leaving x and y to their default values without at least explicitly set them (to their default value, if you need them to be that way).

        Thanks for these top notch lessons ;)
        Have a good day

  • Akshay Chavan

    In foo.h

    Shouldn't it be

  • Matt

    At the end of section "Default parameters can only be declared once", you wrote:

    "Rule: If the function has a forward declaration, put the default parameters there. Otherwise, put them on the function definition."

    Did you mean to write "on", or did you mean "in"?

  • Kattencrack Kledge

    Little typo on one of the function prototypes:

    I'm pretty sure you meant rollDice than rollDie XD

    • Alex

      Nope. Die is actually the singular of dice, and in this case, we are just rolling one die, not multiple dice. Though enough people don't know this that I suspect it will be acceptable to use dice in both situations in the near future (if we haven't hit that point already).

  • Jim

    This code uses the same name and parameters except one has a capital V and the other uses a lower case v.
    Why wouldn't the compiler catch this? Or is this a typo?
    void printvalues(int x, int y=10);

    void printValues(int x, int y=10) // error: redefinition of default parameter
        std::cout << "x: " << x << '\n';
        std::cout << "y: " << y << '\n';

  • Alex, is there any way to forward declare a function that has default pararmeters in it...?

    #include <iostream>

    void val(int, int);

    int main()
        int value = 10;
        return 0;

    void val(int nval, int val2 = 20)
        std::cout << nval << "\n";
        std::cout << val2 << "\n";

    This program gives an error at line 8:

    "Fire.cpp|8|error: too few arguments to function 'void val(int, int)'|"

    and if I remove an int, compiler says that it is unable to find a function with only 1 int parameter.

    • Alex

      Put the default parameter in the forward declaration:

  • kekie

    Shouldn't they be called 'Default arguments'?

  • Sphingine

    Can i give d definition as:

    void printvalues(int nvalue1=0, int nvalue2=2)

    cout<<"1st : "<< nvalue1<< endl;
    cout<<"2st : "<< nvalue2<< endl;


    and call the function as:


  • dave

    I must say this site is awesome and clean looking..specially how the code is displayed....looks neat! keep up good work and i am doing last min craming when i googled default wish me luck! :)

Leave a Comment

Put all code inside code tags: [code]your code here[/code]