Insertion in map using array - error: cannot bind rvalue reference of type ‘int&&’ to lvalue of type ‘int’

Viewed 629

I want to insert values of two arrays : A and T in an std::unordered_map (named unordered) by following code:

for(int i = 0; i < N; ++i)
{   
    unordered.insert(std::make_pair<int, int>(A[i], T[i]));
}

I am getting the following error:

error: cannot bind rvalue reference of type ‘int&&’ to lvalue of type ‘int’

I guess it is because the operator[] returns a reference to a variable, but then how to do it otherwise?

This is the rest of my code:

int N;
cin >> N;

int A[N], T[N];

std::unordered_map<int, int> unordered;

for (int i = 0; i < N; ++i)
{
    cin >> A[i];
}
for (int i = 0; i < N; ++i)
{
    cin >> T[i];
}
for (int i = 0; i < N; ++i)
{
    unordered.insert(std::make_pair<int, int>(A[i], T[i]));
}
2 Answers

How to do it otherwise?

You are explicitly providing the template parameters of std::make_pair to make the compiler to forcefully choose the following std::make_pair's overload

template< class T1, class T2 >
std::pair<V1,V2> make_pair( T1&& t, T2&& u );

This is not required, let the compiler do the deduction

unordered.insert(std::make_pair(A[i], T[i]));

or

unordered.insert({A[i], T[i]});

or using std::unordered_map::emplace

unordered.emplace(A[i], T[i]);

Note that the A and T are variable length arrays, which are not part of standard c++. More read: Why aren't variable-length arrays part of the C++ standard? Use std::vector instead of the VLAs.

That being said, do you really need to store the user input in between to an array! You could also directly insert the key-values to the map on the go as follows:

#include <iostream>
#include <unordered_map>

int main() 
{
    int N; std::cin >> N;

    std::unordered_map<int, int> unordered;

    for (auto i = 0u; i < N; ++i)
    {
        int key{}, value{};
        std::cin >> key >> value;      // get the user input (key and value)
        unordered.emplace(key, value); // like this
        // or
        // unordered.insert(std::make_pair(key, value));
        // or
        // unordered.insert({ key, value });        
    }
}

Coceptually you can use std::move as shown below.

unordered.insert(std::make_pair<int, int>(std::move(A[i]),std::move( T[i])));
Related