struct User {
std::string email;
std::string password;
int pin;
};
int main() {
User jason{"jason@mail.com", "Passw0rd!", 1234}; // good old struct initialization
User jane{.email = "jane@mail.com", .password = "Passw0rd!"}; // designated initialization
}-
Only for aggregate types
An aggregate is an array or a class with
-
no user-declared or inherited constructors
-
no private or protected non-static data members
-
no virtual functions
-
no virtual, private, or protected base classes
struct Widget { Widget() = delete; }; Widget w; // error Widget w{}; // ok in C++17 whereas in C++20 it is error
-
-
All designators used in the expression must appear in the same order as the data members, e.g.
User user{.password = "Passw0rd!", .email = "user@mail.com"};error: ISO C++ requires field designators to be specified in declaration order ...
- Also, cannot be mixed with regular initializers
User user{.email = "user@mail.com", "Passw0rd!"};error: mixture of designated and non-designated initializers in the same initializer list ...
constinit specifies that a variable must have a static initialization.
constinit cannot be used together with constexpr or consteval.
const char* AllocateDynamicString() {
return "Dynamic init";
}
constexpr const char* GetString(bool isConstInit) {
return isConstInit ? "Const init" : AllocateDynamicString();
}
constinit const char* str = GetString(true); // ok
constinit const char* str = GetString(false); // error: variable does not have a constant initializer📎 constinit can only be applied to variables with static or thread storage duration.
It does not make sense to apply it to other variables, as constinit is all about static initialization.
for (const auto& user : GetDatabase().selectActiveUsers()) { // not good enough
// ...
}Maybe undefined behaviour because
GetDatabase()might returns a reference.
{
auto db = GetDatabase();
for (const auto& user : db.selectActiveUsers()) { // good
// ...
}
}for (const auto db = GetDatabase(); const auto& user : db.selectActiveUsers()) { // better
// ...
}