Vector van structs-initialisatie

Ik wil weten hoe ik waarden kan toevoegen aan mijn vector van structs met behulp van de push_backmethode

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

Dus hoe kan ik er nu elementen aan toevoegen?

Ik heb een functie die de stringnaam initialiseert (onderwerpnaam eraan)

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);
}

Functie-oproep

setName("english", "math", "physics" ... "economics");

Antwoord 1, autoriteit 100%

Maak vector, push_back-element en wijzig het als volgt:

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;
}

Je hebt geen toegang tot een vector met [#] totdat er een element bestaat in de vector op die index. Dit voorbeeld vult de [#] en wijzigt deze daarna.


Antwoord 2, autoriteit 58%

Als u de nieuwe huidige standaard wilt gebruiken, kunt u dit doen:

sub.emplace_back ("Math", 70, 0);

of

sub.push_back ({"Math", 70, 0});

Deze vereisen geen standaardconstructie van subject.


Antwoord 3, autoriteit 17%

U kunt ook kiezen voor geaggregeerde initialisatie van een accolade-initialisatielijst voor situaties als deze.

#include <vector>
using namespace std;
struct subject {
    string name;
    int    marks;
    int    credits;
};
int main() {
    vector<subject> sub {
      {"english", 10, 0},
      {"math"   , 20, 5}
    };
}

Soms zijn de leden van een struct echter niet zo eenvoudig, dus je moet de compiler een handje helpen bij het afleiden van de typen.

Dus voortbouwend op het bovenstaande.

#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}
                         }}
    };
}

Zonder de assessmentin de braced initializer zal de compiler mislukken bij een poging om het type af te leiden.

Het bovenstaande is gecompileerd en getest met gcc in c++17. Het zou echter moeten werken vanaf c++11 en hoger. In C++ 20 kunnen we de syntaxis van de aanduiding zien, ik hoop dat dit het volgende mogelijk maakt

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

bron: http://en.cppreference.com/w/cpp/language/ aggregatie_initialisatie


Antwoord 4, autoriteit 13%

U kunt geen toegang krijgen tot elementen van een lege vector met een subscript.
Controleer altijd of de vector niet leeg is & de index is geldig bij gebruik van de operator []op std::vector.
[]voegt geen elementen toe als deze niet bestaan, maar veroorzaakt een Undefined Behaviourals de index ongeldig is.

U moet een tijdelijk object van uw structuur maken, dit opvullen en vervolgens toevoegen aan de vector, met behulp van vector::push_back()

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

Antwoord 5, autoriteit 3%

Na het geaccepteerde antwoord te hebben bekeken, realiseerde ik me dat als we de grootte van de vereiste vector weten, we een lus moeten gebruiken om elk element te initialiseren

Maar ik vond een nieuwe manier om dit te doen met default_structure_element zoals het volgende…

#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;
  } 
}

Dan denk ik dat het goed is om een vector van de struct te initialiseren, toch?

Other episodes