Raginator
Raginator

Reputation: 117

Why does the following compile if the non-POD constant isn't explicitly defined?

I was under the impression that all const members had to be explicitly initialized by the constructor once, but after testing it seems as if only POD types have to be initialized. The following compiles regardless of whether b is mentioned in the constructor or not:

#include <string>

struct A {
    const int a;
    const std::string b;

    A() : a{} {}
};

Example: http://cpp.sh/36my2

Upvotes: 1

Views: 108

Answers (2)

M.M
M.M

Reputation: 141628

This is covered by C++14 [dcl.init]/7:

If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor.

Providing no initializer for an object, in this context, is "calling for default initialization". "User-provided default constructor" means that there is a constructor defined that can be called with zero arguments, and that constructor was not set to =default;.

The std::string class does in fact have a user-provided default constructor. So this rule prevents you from omitting a{}, but it does not force you to provide any initializer for b.

Upvotes: 2

std::string has a user supplied default constructor, so default constructing b will give it a "meaningful" value (it will be an empty string). The constructor can therefore default initialize it implicitly.

int however is a trivially constructible type. Its default constructor does absolutely nothing, so the content of a is indeterminate unless explicitly initialized in the member initializer list. List initializing (using braces {}) a will preform value initialization on it, and will end up giving it the well defined value of 0.

The member variables must be initialized with a meaningful value, because the program cannot change them afterwards. That's the rationale behind demanding an initializer.

Upvotes: 1

Related Questions