Adrian Muljadi
Adrian Muljadi

Reputation: 168

C++ Initializing a vector inside a struct definition

I'm reading through Programming Principles and Practice C++, and came across the following piece of code which I don't think was well explained

struct Day {
    vector<double> hour{vector<double>(24,-777) };
};

What is happening here? I usually use this initializer when I need a vector of a certain length with default values:

vector<double> hour(24, -777);

However, this way of initializing does not work inside the struct,

struct Day {
    vector<double> hour(24, -777);
};

Results in a compile error

Error (active)      expected a type specifier   HelloWorld  d:\Visual Studio 2015\HelloWorld\HelloWorld\HelloWorld.cpp  11  
Error (active)      expected a type specifier   HelloWorld  d:\Visual Studio 2015\HelloWorld\HelloWorld\HelloWorld.cpp  11  
Error   C2059   syntax error: 'constant'    HelloWorld  d:\visual studio 2015\helloworld\helloworld\helloworld.cpp  11  

Looking for an explanation behind the initializers.

I'm using MS Visual Studio 2015

Upvotes: 4

Views: 4363

Answers (4)

Patryk Obara
Patryk Obara

Reputation: 1847

C++11 lifted restrictions on in-class initialization and introduced initializer_list constructors for collections allowing you to write this:

struct Day {
    std::vector<double> hours = { 1.0, 2.0, 3.0 };
};

However for your case (vector filled with 24 values of -777.0), you don't want initializer_list - you still can use old constructor, but unfortunately you can't combine it with auto (unless it's static constexpr literal member). You should probably use 24u to parameter, that's intended to be converted to size_t and double for parameter intended to be value (for readability):

struct Day {
    std::vector<double> hours = std::vector<double>(24u, -777.);
};

Example with using auto to initialize some member:

struct Day {
    static constexpr auto default_hours_size = 24u;
    std::vector<double> hours = std::vector<double>(default_hours_size, -777.);
};

Upvotes: 0

Jonathan Mee
Jonathan Mee

Reputation: 38919

This works fine in Visual Studio 2015: http://rextester.com/WIS16088 Perhaps you're doing something else wrong in your code?

Anyway to explain what's going on here:

  1. The behavior of curry braces here was clarified in N3922 which in this case will distill to a braced-init-list, there is some great further reading here: What Is a Curly-Brace Enclosed List If Not an intializer_list?
  2. These curly braces are providing default member initialization for the member hours, as provided by C++11. This is the value that hours will take on unless it:

Also appears in the member initialization list in a constructor

  1. Finally let's talk about the value that is being used in the curly braces which is hours brace-init-list, that's clearly a vector<int> http://en.cppreference.com/w/cpp/container/vector/vector defines that as the 2nd constructor which:

Constructs the container with count copies of elements with value value

So what you'll end up with is hours initialized to contain 24 ints of value -777 if it is default initialized.

Upvotes: 0

Adam Hunyadi
Adam Hunyadi

Reputation: 1952

Your solution should be valid. If it does not work, try doing this:

struct Day {
    vector<double> hour = vector<double>(24,7);
};

Upvotes: -1

Hatted Rooster
Hatted Rooster

Reputation: 36483

vector<double>(24,-777)

This creates a temporary std::vector with 24 values of -777.

Then the hour vector is constructed by using that temporary, using the move constructor.

Upvotes: 4

Related Questions