inserting a class object into a map??

Hey yall, so we have an assignment dealing with maps, and I think I understand them, but I cannot get this one to work. I have a class (Apps) that contains a string for the name, a string for the type, and a float for the cost, and I want the name string to be the Key value for the map. I think I initialized the map correctly, but on line 2 I am getting the error "missing template arguments before '(' token". I understand that means I'm missing some a character somewhere, but in all the examples I'm seeing I have exactly what they have. I'd also like to insert already constructed objects, but I don't know if that is possible considering the emplace function. If anyone has any ideas or thoughts I'd really appreciate them!

1
2
  std::map<string, Apps> Appmap;
  Appmap.insert(std::pair(1, Apps(AppName[0], AppPrice[0], AppType[0])));


For the syntactical issue, it's saying you need std::pair<TypeA, TypeB>(...) and not just std::pair(...). I think this can be automatically determined by the compiler in either C++17 or C++20, but don't quote me on that.

But notice your map is a mapping of string to 'Apps', but the first element of your pair is an int. If we change the map to <int, Apps>, then things work better.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Example program
#include <iostream>
#include <string>
#include <map>
#include <utility>

using std::string;

struct Apps {
    Apps(string name, int price, string type)
    : name(name), price(price), type(type) { }
    
    bool operator<(const Apps& other)
    {
        return name < other.name;   
    }
    
    string name;
    int price;
    string type;  
};

int main()
{
    string AppName[] = { "TestName", "Unused" };
    int AppPrice[] = { 42, 0 };
    string AppType[] = { "TestType", "Unused" };
    
    std::map<int, Apps> Appmap;
    Appmap.insert(std::pair<int, Apps>(1, Apps(AppName[0], AppPrice[0], AppType[0]))); 
}


I'd also like to insert already constructed objects
There's nothing really special needed to do this. You'd just create some named variable before the insert call.
1
2
    Apps my_apps(AppName[0], AppPrice[0], AppType[0]);
    Appmap.insert(std::pair<int, Apps>(1, my_apps)); 
Last edited on
If you want to use name as key, then do so:
1
2
3
std::map<string, Apps> Appmap;
Appmap.insert( std::make_pair( AppName[0], Apps(AppName[0], AppPrice[0], AppType[0]) ) );
Appmap[ AppName[1] ] = Apps(AppName[1], AppPrice[1], AppType[1]); // less efficient for add 

The std::make_pair is a function template and picks the types from arguments unlike class template std::pair.
Last edited on
Ganado, is right. You don't need to specify the template arguments to std::pair thanks to class template argument deduction (CTAD) that was introduced in C++17. The only problem with your code (using a modern compiler) is that you pass an int and not a string as the first argument when constructing the std::pair.

1
2
std::map<std::string, Apps> Appmap;
Appmap.insert(std::pair(AppName[0], Apps(AppName[0], AppPrice[0], AppType[0])));

You can even leave out std::pair and just put the arguments inside { }. The compiler knows that the insert function expects a std::pair<std::string, Apps> and will automatically deduce that is what you want to construct.

1
2
std::map<std::string, Apps> Appmap;
Appmap.insert({AppName[0], Apps(AppName[0], AppPrice[0], AppType[0])});

Last edited on
Thank you all for the responses, Ganado was very helpful but Peter87 had it really clean too, thanks to the both of you for the help!
Topic archived. No new replies allowed.