结构初始化向量

我想知道如何使用 push_back方法将值添加到结构的向量中

struct subject
{
string name;
int marks;
int credits;
};




vector<subject> sub;

那么现在我如何向它添加元素呢?

我有一个初始化字符串名称(主题名称)的函数

void setName(string s1, string s2, ...... string s6)
{
// how can i set name too sub[0].name= "english", sub[1].name = "math" etc


sub[0].name = s1 // gives segmentation fault; so how do I use push_back method?


sub.name.push_back(s1);
sub.name.push_back(s2);
sub.name.push_back(s3);
sub.name.push_back(s4);


sub.name.push_back(s6);


}

函数调用

setName("english", "math", "physics" ... "economics");
352172 次浏览

You cannot access elements of an empty vector by subscript.
Always check that the vector is not empty & the index is valid while using the [] operator on std::vector.
[] does not add elements if none exists, but it causes an Undefined Behavior if the index is invalid.

You should create a temporary object of your structure, fill it up and then add it to the vector, using vector::push_back()

subject subObj;
subObj.name = s1;
sub.push_back(subObj);

Create vector, push_back element, then modify it as so:

struct subject {
string name;
int marks;
int credits;
};




int main() {
vector<subject> sub;


//Push back new subject created with default constructor.
sub.push_back(subject());


//Vector now has 1 element @ index 0, so modify it.
sub[0].name = "english";


//Add a new element if you want another:
sub.push_back(subject());


//Modify its name and marks.
sub[1].name = "math";
sub[1].marks = 90;
}

You cant access a vector with [#] until an element exists in the vector at that index. This example populates the [#] and then modifies it afterward.

If you want to use the new current standard, you can do so:

sub.emplace_back ("Math", 70, 0); // requires a fitting constructor, though

or

sub.push_back ({"Math", 70, 0}); // works without constructor

.

You may also which to use aggregate initialization from a braced initialization list for situations like these.

#include <vector>
using namespace std;


struct subject {
string name;
int    marks;
int    credits;
};


int main() {
vector<subject> sub {
{"english", 10, 0},
{"math"   , 20, 5}
};
}

Sometimes however, the members of a struct may not be so simple, so you must give the compiler a hand in deducing its types.

So extending on the above.

#include <vector>
using namespace std;


struct assessment {
int   points;
int   total;
float percentage;
};


struct subject {
string name;
int    marks;
int    credits;
vector<assessment> assessments;
};


int main() {
vector<subject> sub {
{"english", 10, 0, {
assessment{1,3,0.33f},
assessment{2,3,0.66f},
assessment{3,3,1.00f}
}},
{"math"   , 20, 5, {
assessment{2,4,0.50f}
}}
};
}

Without the assessment in the braced initializer the compiler will fail when attempting to deduce the type.

The above has been compiled and tested with gcc in c++17. It should however work from c++11 and onward. In c++20 we may see the designator syntax, my hope is that it will allow for for the following

  {"english", 10, 0, .assessments{
{1,3,0.33f},
{2,3,0.66f},
{3,3,1.00f}
}},

source: http://en.cppreference.com/w/cpp/language/aggregate_initialization

After looking on the accepted answer I realized that if know size of required vector then we have to use a loop to initialize every element

But I found new to do this using default_structure_element like following...

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;


typedef struct subject {
string name;
int marks;
int credits;
}subject;


int main(){
subject default_subject;
default_subject.name="NONE";
default_subject.marks = 0;
default_subject.credits = 0;


vector <subject> sub(10,default_subject);         // default_subject to initialize


//to check is it initialised
for(ll i=0;i<sub.size();i++) {
cout << sub[i].name << " " << sub[i].marks << " " << sub[i].credits << endl;
}
}

Then I think its good to way to initialize a vector of the struct, isn't it?