Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the initialization order of the vector elements guaranteed by the standard?

To fill a std::vector<struct_name> from std::cin, I usually write as following code:

struct point{
    int x, y;
};

int main()
{
   std::size_t n;
   std::cin>>n; 
   std::vector<point> vec(n);
    for (auto& p:vec) 
        std::cin>>p.x>>p.y;
   //...
}

But today I found out another way to do it with default constructor:

struct point{
int x, y;
   point(){
      std::cin>>x>>y;
   }
};

int main()
{
    std::size_t n;
    std::cin>>n; 
    std::vector<point> vec(n);
    //...
}

Questions:

  1. Is the initialization order of the vector elements guaranteed by the standard(0,1,2,n-1...)?
  2. (If answer of previous question is true) Is really the second variant has twice effective?

I am interested in behavior according to the C++11(and newer) standard

like image 636
PavelDev Avatar asked Dec 14 '20 01:12

PavelDev


People also ask

What is the order of initialization for data?

In the initializer list, the order of execution takes place according to the order of declaration of member variables. While using the initializer list for a class in C++, the order of declaration of member variables affects the output of the program. Program 1: C++

What is the correct way to initialize vector in?

Begin Declare v of vector type. Call push_back() function to insert values into vector v. Print “Vector elements:”. for (int a : v) print all the elements of variable a.

How do you initialize a vector by its default value?

By default, the size of the vector automatically changes when appending elements. To initialize the map with a random default value, below is the approach: Approach: Declare a vector. Set the size of the vector to the user defined size N.

Does Vector maintain order?

Java ArrayList and Vector both implements List interface and maintains insertion order.


2 Answers

It is not guaranteed that the elements are initialized in the order of their indices. In C++11, see [vector.cons]/3:

Effects: Constructs a vector with n value-initialized elements.

This says nothing about the ordering, so nothing can be assumed. The wording changes in later editions of the standard, but no ordering ever seems to have been imposed.

like image 121
Brian Bi Avatar answered Oct 16 '22 16:10

Brian Bi


On your first question, the C++20 (but this goes back to C++11 as well) section dealing with the vector sequence container makes no promises about the order in which elements are constructed within the vector itself, only that the elements are set to some specific value:

Effects: Constructs a vector with n default-inserted elements.

Nothing at all about the order in that (very brief) section(a).

But you have a bigger problem with your method, specifically I don't think you really want to go out to cin for every case where you're default constructing a point variable.

There may be, for example, cases where you need a default-constructed temporary variable and it's going to be seen as a hang if your program suddenly stops to accept user input, especially without some prompt to the user :-)


That makes your second question moot but, assuming you're concerned about inefficiencies in initialising vector elements then changing them with an input loop, I wouldn't be. The structure with no constructor (i.e., just a couple of int variables) doesn't need to initialise them(b), so a vector of them can just do the allocation and stop there.


(a) Some order is guaranteed in the standard, such as the order of disparate members within a class, or the order of elements within an array. However, the elements of a vector are neither of those things.


(b) This is covered in C++20 10.9 Iniitialisation [class.init]:

When no initializer is specified for an object of (possibly cv-qualified) class type (or array thereof), or the initializer has the form (), the object is initialized as specified in 9.3.

and C++20 9.3 Initializers [dcl.init]:

To default-initialize an object of type T means:

  • If T is a (possibly cv-qualified) class type, constructors are considered. The applicable constructors are enumerated, and the best one for the initializer () is chosen through overload resolution. The constructor thus selected is called, with an empty argument list, to initialize the object.
  • If T is an array type, each element is default-initialized.
  • Otherwise, no initialization is performed.

It's that first bullet point that kicks in for a type with no constructors explicitly defined or inherited. In that case, it uses the implicitly-defined constructor which is equivalent to a user defined constructor with no body and no initialiser list.

like image 6
paxdiablo Avatar answered Oct 16 '22 15:10

paxdiablo