In C 20, for a type like this:
struct Person {
std::string name;
int age;
};
We can return it from a function using aggregate initialization, with or without writing out the type name:
Person getJohn()
{
// With type name
return Person {
.name = "John",
.age = 42,
};
// Without type name
return {
.name = "John",
.age = 42,
};
}
What's the difference between specifying and not specifying the type name explicitly? One thing I noticed is that without a type name, if I mess up the field names/order, the error message given by my compiler and IDE is less clear than if I have a type name. But other than that, are the two forms semantically different in any way?
CodePudding user response:
They should always be equivalent. A return statement performs copy-initialization ([stmt.return]/2). A copy-initialization from a designated-initializer-list performs aggregate initialization ([dcl.init.list]/3.1). If the operand is simply the designated-initializer-list itself, we are done. The return object has been aggregate-initialized. If the operand is Person designated-initializer-list, then guaranteed copy elision applies ([dcl.init.general]/16.6.1) which again means that the return object is simply aggregate-initialized (there is no additional temporary object).
Omitting the type can only make a difference in non-aggregate-initialization contexts: if the user-defined constructor selected for the initialization has been declared explicit, the program is ill-formed. But aggregate initialization doesn't use a constructor.
