c++constructorstdmap

Cannot insert keys and values in a map


I'd been trying to insert some key and values in the following way, but I'm getting an error:

error: no matching constructor for initialization of 'Edge'

I'm using C++17.

This is my program:

#include <iostream>
#include <string>
#include <map>

struct Edge
{
    int v1{};
    int v2{};

    Edge (int v1, int v2)
    :v1{v1}, v2{v2}
    {
    }

};

int main()
{
    std::map<std::string, Edge> mymap;

    mymap["edge1"] = Edge(0,0);
    mymap["edge2"] = Edge(1,1);

    return 0;
}

I'm pretty sure my constructor is correct, but any help is highly appreciated.


Solution

  • #include <iostream>
    #include <string>
    #include <map>
    
    struct Edge
    {
        int v1{};
        int v2{};
        Edge() = default;
        Edge(int v1, int v2) : v1{v1}, v2{v2} {}
    };
    
    int main()
    {
        std::map<std::string, Edge> mymap;
    
        mymap.emplace("edge1", Edge(0, 0));
        mymap.emplace("edge2", Edge(1, 1));
        mymap.emplace("edge2", Edge(2, 2));
        mymap.emplace("edge3", Edge(3, 3));
    
        for (const auto &pair : mymap)
        {
            std::cout << pair.first << " " << pair.second.v1 << " " << pair.second.v2 << std::endl;
        }
        return 0;
    }
    

    Note:

    operator[] first checks the container to see if the element already exists. If exists, a reference to the existing element is returned. If not, a new element is default constructed in the container and a reference to it is returned. Since Edge has no default constructor, this cannot happen and the program fails to compile. If Edge had a default constructor, the returned element would then be assigned the value of the temporary Edge the asker wanted to insert.

    On the other hand, Emplace() constructs the new Edge "in place" and avoids the need to construct a temporary and copy or move it, which is a bit more efficient.

    Useful link:

    Overview of std::map’s Insertion / Emplacement Methods in C++17