I've been working on my new project in c (database of students) made on std::unordered_map
and I have problem with returning values from map. I have a code:
Preambule.h
#include <string>
#include <unordered_map>
#include <vector>
namespace data
{
struct student
{
std::string name;
std::string surname;
uint8_t age;
uint8_t year;
};
student makestudent(std::string m_name, std::string m_surname, uint8_t m_age, uint8_t m_year)
{
student s = {m_name, m_surname, m_age, m_year};
return s;
};
void addnew(int ID,std::vector<int8_t> keys,std::unordered_map<int8_t,data::student> students, std::string m_name, std::string m_surname, uint8_t m_age, uint8_t m_year)
{
ID = 1;
keys.push_back(ID);
students[ID] = makestudent(m_name,m_surname,m_age,m_year);
}
}
main.cpp
#include <string>
#include <iostream>
#include <unordered_map>
#include "preambule.h"
int main()
{
int *ID = new int(0);
std::vector<int8_t>* keys = new std::vector<int8_t>;
std::unordered_map<int8_t, data::student> *students = new std::unordered_map<int8_t, data::student>;
data::addnew(*ID,*keys,*students, "name", "surname", /*age*/ 1, /*year*/ 1);
data::addnew(*ID,*keys,*students, "name", "surname", /*age*/ 1, /*year*/ 1);
data::student &ben = students[1];
std::cout << ben.age;
delete students;
delete keys;
delete ID;
return EXIT_SUCCESS;
}
After trying to return values from map:
data::student &ben = students[1];
I keep getting error message:
non-const lvalue reference to type
data::student
cannot bind to a value of unrelated typestd::unordered_map<int8_t, data::student>
(akaunordered_map<signed char, data::student>
)
How can I fix it?
CodePudding user response:
data::student &ben = students[1];
The students variable is not of map type here, it's of the pointer type std::unordered_map<int8_t, data::student> *
, thus the subscript operator actually does a pointer offset operation and dereferences it here (*(students 1)
). Instead you probably want to dereference the pointer (to access the underlying map) and take the value by key:
data::student &ben = (*students)[1];
You will not find the data you expect from the map, however, because the function which is supposed to populate the map with data takes it by value:
void addnew(int ID,std::vector<int8_t> keys,std::unordered_map<int8_t,data::student> students, std::string m_name, std::string m_surname, uint8_t m_age, uint8_t m_year)
As a result you always instantiate a new copy of the map and all new data comes into this copy, while your original instance never changes. Pass the map by a reference (std::unordered_map<int8_t,data::student> &students
) or pointer (std::unordered_map<int8_t,data::student> *students
) if you want to change the original object.
CodePudding user response:
Change:
data::student &ben = students[1];
To:
data::student &ben = students->at(1);
students
is a pointer and you need to dereference it before you access member functions like operator []