Search code examples
c++default-valuedefault-constructorinitialization

c++ default argument vs. initalizer list


There are four specific cases , where you must specify default initializer list. Fully discussed here

In short, if you have

Initializer list Required

  1. non-static const data members
  2. data member of reference type
  3. provide params to data members which are objects of other class
  4. provide base class ctor parameters from derived class.

The one drawback to default argument seems to be that the default arguments must be the trailing parameters in the function prototype parameter list. For example:

drawbacks(???) to default arguments

void f(int, int = 2, int = 3);     // trailing defaults
void g(int = 1, int = 2, int c);   // error
void h(int, int = 3, int);         // error

My question is, if my code does not fall in between the 4 required cases for initializer list and always requires all parameters to have default values, i.e. does not lead to the drawbacks to default arguments , which one should I choose and why? What is the best practice?

an example being

// option -1: for the default argument list
// my_array.h
my_array(int a_number_of_elements = 0, int default_val = 0);

//option-2 : default initalizer list
// my_array.h
my_array(int a_number_of_elements, int default_val);
//my_array.cpp
my_array:: my_array(int a_number_of_elements, int default_val)
                   : my_num_elements(a_num_elements), my_default_value(default_val)

Thanks for looking.


Solution

  • You are dealing with two completely different things here: constructor initializer lists vs default function arguments.

    You got most of what you said correctly, but contrary to what you might believe, default constructor arguments do not imply the construction of data members using these values, unless you explicitly state so. Hence, one technique is not a replacement for the other, just separate complementary things.

    For example:

    // my_array.h
    my_array(int a_number_of_elements = 1, int default_val = 0);
    //my_array.cpp
    my_array:: my_array(int a_number_of_elements, int default_val)
                       : my_num_elements(a_num_elements), my_default_value(default_val)
    

    will [be expected to] initialize an array with one element of value zero.

    If you do not explicitly call the constructors of the data members, then their default constructors, if available, will be called, so the following two are equivalent.

    //implicitly default constructing members
    my_array:: my_array()
    {}
    //explicitly default constructing members
    my_array:: my_array() :
        my_num_elements(), my_default_value()
    {}
    

    Regarding the two above, it is always a good idea to leave things explicit for better legibility. As often said, a given code is usually written once, but read many times.