Initializing objects (instances of classes or structs) in C++ can be done in various ways. Some syntaxes evoke a direct-initialization of your object, other
In general:
T s(...);
or T s{...};
is direct-initializationT s = ...;
is copy-initialization1In copy-initialization, the right-hand side is implicitly converted to a temporary instance of the type T
, from which s
is subsequently copy/move-constructed.
Mr. Stroustrup presents these different initialization styles as equal.
In many cases the generated (optimized) code is indeed exactly the same. Compilers are allowed to elide the copy construction (even if it has side effects). Modern compilers are well beyond simple optimizations such as this one so you can effectively count on this elision (which is required in C++17).
The difference between copy and direct initialization is nevertheless very important because the semantics are different; for example, invoking constructors declared explicit
is only possible in direct-initialization.
1 The form T s = {...};
is copy-list-initialization and follows some special list-initialization rules.
You can easily look up the answers to these sorts of questions. That said, the simple answer is that an =
means copy-initialization. However, T t={...};
is copy-list-initialization, which (unless the braces contain only a T
or something derived from it) does not involve a copy! It does, however, disallow the use of non-explicit
constructors.
obj s = obj("value");
This is direct initialization of a prvalue, which is then used to copy initialize the variable s
. C++17's prvalue rules make this de-facto direct initialization of s
.
obj s{"value"};
This is direct-list-initialization. The "list" part is important. Anytime you apply a braced-init-list for the purposes of initializing an object, you are performing list-initialization.
obj s = {"value"};
This is copy-list-initialization.
obj s = obj{"value"};
This is direct-list-initialization of a prvalue, which is then used to copy initialize the variable s
.
obj s("value");
That is direct initialization.
obj s = "value";
That's copy initialization.
Mr. Stroustrup presents these different initialization styles as equal.
They are equal in the sense that they do mostly the same thing. But they're not technically equal; copy-list-initialization cannot call explicit
constructors. So if the selected constructor were explicit
, the code would fail to compile in the copy-list-initialization cases.