0
votes

Reading cppreference on value initialization, I have come to this:

  1. if T is a class type with no default constructor or with a user-provided or deleted default constructor, the object is default-initialized;

And example:

struct T3
{
    int mem1;
    std::string mem2;
    T3() { } // user-provided default constructor
};

Reading article on default initialization

if T is a non-POD (until C++11) class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object;

if T is an array type, every element of the array is default-initialized;

otherwise, nothing is done: the objects with automatic storage duration (and their subobjects) are initialized to indeterminate values.

This applies to the example, T is class type, which means the overload resolution should select the candidate to initialize the values ( the user-provided default constructor ), but it is empty, so mem1 should stay with indetermined values (that's true ) but same should be mem2, but that is "default initialized" to "", why is that? Does it work recursively? Every member of T that is class type is subjected to first rule?

I'm quite confused right now.


2)if T is a class type with a default constructor that is neither user-provided nor deleted (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized and then it is default-initialized if it has a non-trivial default constructor;

And example:

struct T1
{
    int mem1;
    std::string mem2;
}; // implicit default constructor

the mem1 is zero-initialized to 0, however what does "non-trivial" default contructor means? mem2 is also default-initialized to "", howevever i am still unsure, what does "non-trivial default constructor" means? The default constructor should be generated by compiler, however how does it decide what is and what is not non-trivial --- if non-trivial default constructor means that it has to initialize objects -- same question as above, does it mean that every object is initialized with default constructor?

2
Remember: T3() { } is not the same as T3() = default; or not writing the ctor at all (which is the same as = default). - Jesper Juhl
See en.cppreference.com/w/cpp/language/default_constructor - the "Trivial default constructor" section. - Jesper Juhl

2 Answers

3
votes

same should be mem2, but that is "default initialized" to "", why is that? Does it work recursively? Every member of T that is class type is subjected to first rule?

Your suspicion is correct. When you default initialize the class you default initialize each of its members since no initialization was specified in your constructor. Since std::string has a user provided default constructor that is called and it initializes the string object to nothing.

however what does "non-trivial" default contructor means?

A trivial constructor is a do nothing constructor. For a type T it's constructor is trivial if

  • The constructor is not user-provided (that is, implicitly-defined or defaulted)
  • T has no virtual member functions
  • T has no virtual base classes
  • T has no non-static members with brace-or-equal initializers.
  • Every direct base of T has a trivial default constructor
  • Every non-static member of class type has a trivial default constructor

So in T1's case you do not have a trivial constructor because std::string's default constructor is non trivial.

0
votes

This applies to the examle, T is class type, which means the overload resolution should select the candidate to inicialize the values ( the user-provided default constructor ), but it is empty, so mem1 should stay with inderermined values (thats true ) but same should be mem2, but that is "default initialized" to "", why is that?

If you omit a data member from the member initializer list then it's default initialized, which for std::string means calling it's default constructor and initializing it to an empty string. Your default constructor has no member initializer list so all the members gets default initialized.

what does "non-trivial" default contructor means?

You can find the requirements for a trivial constructor here. A non-trivial default constructor is just a default constructor that does not respect all of the requirements for a trivial constructor. In short, a trivial default constructor doesn't do anything at all (even under the hood) other than mark the beginning of the lifetime of the object.

does it mean that every object is initialized with default constructor?

As mentioned earlier, the default constructor (like any other constructor) will default initialize any data member that isn't otherwise specified in the member initializer list. Since it's by default empty, default constructors will recursively cause default initialization unless an inner member specifies an alternative initialization using a member initializer list.