Home > Net >  Problem with returning struct from map c
Problem with returning struct from map c

Time:09-19

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 type std::unordered_map<int8_t, data::student> (aka unordered_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 []

  • Related