Suppose the following:
class foo
{
public:
foo() = default;
private:
std::string m_str = "Hello";
};
I am not able to find any documentation on cppreference.com or the C++11 draft that explains what the default constructor will do to m_str here. My natural assumption is that the compiler is smart enough to not initialize m_str
in the defaulted constructor if it has already been initialized in-class, but maybe I'm wrong.
Can anyone explain the initialization behavior here? Any guarantees or is this unspecified?
This is well defined and specified in [class.ctor]/5:
[...] The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement. [...]
So the defaulted constructor performs the same action as:
foo() {}
This in turn applies the brace-or-equal initializer to each data member as appropriate (cf. [class.base.init]/8).
The form of initialization you are using for m_str
is called brace-or-equal-initializer by the standard.
In the first paragraph under Intializers, the standard states:
8.5 Intializers
1 A declarator can specify an initial value for the identifier being declared. The identifier designates a variable being initialized. The process of initialization described in the remainder of 8.5 applies also to initializations specified by other syntactic contexts, such as the initialization of function parameters with argumet expressions (5.2.2) or the initialization of return values (6.6.3).
initializer: brace-or-equal-initializer ( expression-list ) brace-or-equal-initializer: = initializer-clause braced-init-list
And in the section on class members...
9.2 Class members
5 A member can be initialized using a brace-or-equal-initializer.
And in the section on initializing bases and members...
12.6.2 Initializing bases and members
8 In a non-delegating constructor, if a given non-static data member or base class is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer) and the entity is not a virtual base class of an abstract class (10.4), then
— if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initializedas specified in 8.5
Coming to your class,
foo() = default;
is equivalent to:
foo(){}
When a default constructor with no member initializer list is used, the member data are default initialized. In the default initialization process, for members that have a brace-or-equal-initializer, that form is used to initialize them. In your case,
foo(){}
is equivalent to:
foo() : m_str("Hello") {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With