Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

initialization: parenthesis vs. equals sign [duplicate]

What's the difference between

T a(b);

and

T a = b;

and

T a = T(b);

?

like image 801
fredoverflow Avatar asked Dec 17 '10 12:12

fredoverflow


People also ask

What is the difference between direct initialization and copy initialization?

The main difference between these two types of initialization is that the copy initialization creates a separate memory block for the new object. But the direct initialization does not make new memory space. It uses reference variable to point to the previous memory block.

What is meant by copy initialization?

Copy initialization is performed in the following situations: 1) when a named variable (automatic, static, or thread-local) of a non-reference type T is declared with the initializer consisting of an equals sign followed by an expression.

What is uniform initialization in C++?

Uniform initialization is a feature in C++ 11 that allows the usage of a consistent syntax to initialize variables and objects ranging from primitive type to aggregates. In other words, it introduces brace-initialization that uses braces ({}) to enclose initializer values.


Video Answer


2 Answers

T a( b );

is direct initialization, unless it parses as a function declaration, in which case it's a function declaration.

T a = b;

is copy initialization, which means that it works as if a temporary object is constructed on the right hand side, and that a is then copy constructed or, in C++11 and later, possibly move constructed, from that temporary.

The compiler is free to elide (remove) the temporary+copying/moving whenever it can, but a copy or move constructor, whichever would be logically used, must still be accessible and not explicit.

For example, in C++03 you cannot copy-initialize a std::ostringstream, because it doesn't have a copy constructor. In C++11 you can copy-initialize an ostringstream if the initializer is a temporary, which then results in a logical move construction (which however will usually be elided, optimized away). For example, this copy initialization declaration,

ostringstream s = ostringstream( "blah" );

… doesn't compile as C++03, because in C++03 the copy initialization invokes the class' copy constructor, which doesn't exist. It does however compile as C++11, because in C++11 the copy initialization invokes the move constructor. And while (to maintain its illusion of being a stream) a std::ostringstream can't be directly copied, it can be moved.

Another such difference: in C++03 only the copy initialization syntax supports curly braces initializer, which in C++03 you can use when T is an aggregate type such as a raw array. In C++11 the curly braces notation has been extended and generalized as a uniform initialization syntax, so it can be used also with direct initialization. And so the following direct initialization declaration,

int v[]{ 3, 1, 4, 1, 5, 9, 2, 6, 5, 4 };

… does not compile as C++03, but does compile as C++11 and later.

The = copy initialization syntax is the original initialization syntax from C.

And in C++11 and later, due to move semantics, it can be used in a much wider range of cases than in C++03, such as with a std::ostringstream.

like image 79
Cheers and hth. - Alf Avatar answered Oct 19 '22 02:10

Cheers and hth. - Alf


T a(b);

Calls a constructor of a that accepts b. (If b is of the same type, then the copy constructor is called).

T a = b;

a temporary object of type T is created to be constructed by b. Then the copy constructor is called(= is not an assignment in this case and the next case!).

T a = T(b);

Same as above! except that we explicitly constructed a temporary object.

Note that the standard allows total elimination of temporary copies in the second and third case. Also, if b is not of type T, then in the first case T doesn't have to have a copy constructor. In the second and third cases, even though the implementation is free to optimize the whole thing, it still requires an accessible copy constructor. IIRC the standard calls this: copy elision.

like image 24
Khaled Alshaya Avatar answered Oct 19 '22 03:10

Khaled Alshaya