Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

direct-initialization vs direct-list-initialization (C++)

DIRECT-  VS  COPY-INITIALIZATION
Through this question (Is it direct-initialization or copy-initialization?) I learned the differences between direct-initialization and copy-initialization:

direct-initialization                   copy-initialization
-----------------------                 ---------------------

obj s("value");                         obj s = obj("value");
                                        obj s = "value";

obj s{"value"};                         obj s = {"value"};
                                        obj s = obj{"value"};

I mention it here for the sake of completeness. My actual questions for this page are listed in the next paragraph >>

 
DIRECT-INITIALIZATION  VS  DIRECT-LIST-INITIALIZATION
The answers revealed that within the category of direct-initialization, one can make a difference between direct-initialization and direct-list-initialization.:

obj s("value");   // direct-initialization

obj s{"value"};   // direct-list-initialization

I know that list-initialization doesn't allow narrowing, such that an initialization like int x{3.5}; won't compile. But besides this, I got a couple of questions:

 
(1) Is there any difference in compiler output between
obj s("value"); and obj s{"value"};?
Let's consider a compiler without any optimizations. I would like to know any possible technical difference :-)

 
(2) Perhaps I should ask the exact same question for a multi-variable initialization, like:
obj s("val1", "val2"); and obj s{"val1", "val2"};

 
(3) I have noticed that the list-initialization can sometimes call a different constructor, like in:

vector<int> a{10,20};   //Curly braces -> fills the vector with the arguments
vector<int> b(10,20);   //Parentesis -> uses arguments to parameterize some functionality

How is that possible?  
 

DID WE COVER ALL POSSIBLE INITIALIZATIONS HERE?
From my limited knowledge on C++, I believe that all possible initializations of objects (either native-typed or user-defined-typed objects) have been covered in the examples above. Is that correct? Did I overlook something?  
 


PS: I am learning C++ (I do know C, but not yet C++), so please don't be too hard on me ;-)

like image 773
K.Mulier Avatar asked Nov 18 '17 13:11

K.Mulier


People also ask

What is initialization list in C?

Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.

Is initialization list faster?

Conclusion: All other things being equal, your code will run faster if you use initialization lists rather than assignment.

What is direct initialization?

Direct Initialization or Assignment Operator (Syntax) This assigns the value of one object to another object both of which are already exists. Copy initialization is used when a new object is created with some existing object. This is used when we want to assign existing object to new object.

What is std :: initializer_list?

An object of type std::initializer_list<T> is a lightweight proxy object that provides access to an array of objects of type const T .


1 Answers

 
(1) Is there any difference in compiler output between
obj s("value"); and obj s{"value"};?
Let's consider a compiler without any optimizations. I would like to know any possible technical difference :-)

 
(2) Perhaps I should ask the exact same question for a multi-variable initialization, like:
obj s("val1", "val2"); and obj s{"val1", "val2"};

 
(3) I have noticed that the list-initialization can sometimes call a different constructor, like in:

vector<int> a{10,20};   //Curly braces -> fills the vector with the arguments
vector<int> b(10,20);   //Parentesis -> uses arguments to parameterize some functionality

How is that possible?

  • If there is an initializer-list constructor for the class type obj, it will always be preferred over other other constructors for brace-init-initializers (list initialization), in your case obj s{"value"};;

    What this means is that if you have a constructor that takes std::initializer_list<T> as its first parameter and other parameters are defaulted, then it is preferred. Example

    struct A{
        A(std::initializer_list<std::string>);    //Always be preferred for A a{"value"}
        A(std::string);
    };
    

    std::vector<T> and other STL containers have such initializer-list constructors.

  • Otherwise, Overload resolution kicks in and it falls back to any available constructor as selected by the overload resolution process;

  • Otherwise, if the class has no user defined constructors and it's an aggregate type, it initializes the class members directly.


DID WE COVER ALL POSSIBLE INITIALIZATIONS HERE?
From my limited knowledge on C++, I believe that all possible initializations of objects (either native-typed or user-defined-typed objects) have been covered in the examples above. Is that correct? Did I overlook something?

Nope. you didn't. Excluding Reference initialization, there are five ways objects may be initialized in C++.

  • Direct Initialization
  • List Initialization
  • Copy Initialization
  • Value Initialization
  • Aggregate Initialization (only for aggregate types)

You can find more information here

like image 105
WhiZTiM Avatar answered Sep 19 '22 11:09

WhiZTiM