Lin Ma
Lin Ma

Reputation: 10139

Weird compile error regarding to C++ std::pair

Here is the code and error message, any thoughts why? I tried after removing this line of code Building t = beginEndMap[b.id];, compile is ok. But cannot figure out the casual of this line to the error. This line is not pair related, but the compile error is pair related.

Error message,

Error:
  required from 'std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {const int&}; _Args2 = {}; _T1 = const int; _T2 = Building]'

Source code,

struct Building {
    int id;
    int pos;
    int height;
    bool isStart;
    Building(int i, int p, int h, int s) {
        id = i;
        pos = p;
        height = h;
        isStart = s;
    }
};

class Solution {
public:
    vector<pair<int, int>> getSkyline(vector<vector<int>>& buildings) {
        vector<Building> sortedBuilding;
        unordered_map<int, Building> beginEndMap;
        vector<pair<int, int>> result;
        for (Building b : sortedBuilding) {
            Building t = beginEndMap[b.id];
        }
        return result;
    }
};

int main() {

}

Upvotes: 0

Views: 386

Answers (1)

bolov
bolov

Reputation: 75688

Cause

Long story short, if you use unordered_map::operator[] then Building needs to be DefaultConstructible which it isn't. Hence the (criptic) error.

This happens because operator[] will do an insertion if the key is not found.

The requirements go like this:

value_type (a.k.a std::pair<const int, Building> (my note)) must be EmplaceConstructible from

std::piecewise_construct, std::forward_as_tuple(key), std::tuple<>()

When the default allocator is used, this means that key_type (int in your case) must be CopyConstructible and mapped_type (Building in your case) must be DefaultConstructible.

The Solution

is to have a default constructor for Building, or use unordered_map::at which will throw if the key is not found and so it doesn't have this requirement.


why the compile error related to pair other than something related to unsorted_map?

Because std::pair is used internally to store the key-value pairs.

Unordered map is an associative container that contains key-value pairs with unique keys

and because these kind of criptic errors you get when you have templates. C++ concepts are underway, which will (hopefully) improve drastically exactly this kind of errors.


std::unordered_map::operator[]

Upvotes: 2

Related Questions