I made a small console program which has a class called Class_Room. I can make objects of school classrooms from it and store student names, roll numbers and ages in it. The student data are stored in a map. I wanted to make classroom object like this:
Class_Room class8C = {
{"student x", 2}, //2 for rollnumber
{"student y", 3}
};
So i made a conversion constructor:
Class_Room(std::map<int, std::string> map) {
for (std::pair<int, std::string> value : map) {
student_data[value.first] = { value.second, "NIL" };
}
}
but i get errors: no instance of constructor Class_Room::Class_Room matches argument list
"initializing": cannot convert "initializer list" to Class_Room
Here is my whole code:
#include <iostream>
#include <vector>
#include <string>
#include <map>
class Class_Room {
public:
Class_Room(std::map<int, std::string> map) {
for (std::pair<int, std::string> value : map) {
student_data[value.first] = { value.second, "NIL" };
}
}
void new_student(int roll, std::string name, int age = 0)
{
data.clear();
data.push_back(name);
if (age != 0) {
data.push_back(std::to_string(age));
}
else {
data.push_back("NIL");
}
student_data[roll] = data;
}
std::map<int, std::vector<std::string>> get_student_data_map()
{
return student_data;
}
private:
std::map<int, std::vector<std::string>> student_data;
std::vector<std::string> data;
};
std::ostream& operator<< (std::ostream& output, Class_Room classroom)
{
std::map<int, std::vector<std::string>> student_data = classroom.get_student_data_map();
for (std::pair<int, std::vector<std::string>> value : student_data) {
output << value.first << " => " << value.second[0] << ", " << value.second[1] << "\n";
}
return output;
}
int main() {
Class_Room class8C = {{"Ihsan", 2}};
std::cout << class8C;
}
I'm a beginner to c and don't know what went wrong, any help would be appreciated.
CodePudding user response:
There's a bit more to this answer, but I'll go with the thing that will solve your issue, then will try to explain some of the more interesting bits so that you learn something from it.
GIST: Your map is the other way around
// your map has keys of type int, values of type string
Class_Room(std::map<int, std::string> map) { // pairs of <int, string>
for (std::pair<int, std::string> value : map) {
student_data[value.first] = { value.second, "NIL" };
}
}
// and then you want to insert pairs of <string, int>
// keys of type string, values of type int
// like: {"Ihsan", 2}
Inverting those should put you on the right track.
// Class_Room class8C = {{2, "Ihsan"}}; // but this is not enough!
// you actually need something along these lines:
Class_Room class8C{
std::map<int, std::string>{{2, "Ihsan"}}};
// or
Class_Room class8C{
{ // creates the map
{ // creates the pair to insert
2, std::string("Ihsan")
}
}
};
The error you're getting is because the compiler is trying to find the right constructor and it fails.
First, you need a map to pass to your constructor. The compiler will have to figure a way to create that map before calling your ctor (if that map doesn't already exist).
If you look at the constructors for std::map
, you'll notice that the 5th one takes an initializer list: https://en.cppreference.com/w/cpp/container/map/map
The value_type template for that initializer list is also: <int, string>, same as the map itself. So the order matters.
You could have also created the map beforehand, but I guess you want concise code.