Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ std::vector<std::pair<const int, int>> can not insert element

Tags:

c++

c++11

int main() {
  using kv = std::pair<const int ,int>;

  std::vector<kv> vec;
  kv a{1,1};
  vec.insert(vec.begin(),a);
}

I tried to insert element into that vector, but the compiler gives this eerror:

cannot assign to non-static data member 'first' with const-qualified type 'const int'

while push_back() will compile correctly.Why is that? And what's the correct way to insert element into such vector?

ADD: The reason why I use std::pair<const int, int> is that I want to implement something like std::map, and the key in the key-value pair should not be modified. But I'm not sure if std::pair<const int, int> is the correct approach to do this.

like image 580
Ziqi Liu Avatar asked Dec 18 '22 21:12

Ziqi Liu


1 Answers

Let's start by observing the following:

std::pair<const int, int> a, b;

a=b;

This will not compile either. Why? Because you are in effect declaring the following class:

class my_pair {

public:
    // ... Bunch of irrelevant stuff

    const int first;
    int second;
};

This class has its default assignment operator deleted. The default assignment operator is equivalent to assigning class members individually:

pair<first,second> &operator=(const pair<first, second> &other)
{
   first=other.first;
   second=other.second;
   return *this;
}

This is a rough example of what a default assignment operator looks like.

But you can't modify the first class member, here, because it is a const class member. Hence, the default assignment operator is deleted. End result: cannot assign a std::pair with a const value to another such pair.

You should now be able to figure out by yourself why insert() on your vector of pairs doesn't work.

insert() is, roughly, equivalent to shifting over all existing values by one, in the vector, after the insertion point, to make room for the new value. In other words:

 value[n+1]=values[n];

For all values past the insertion point (I'm ignoring for the moment the work done to grow the vector by one value, which is irrelevant to this discussion).

But the default assignment operator, as I explained, is deleted because the value has a const class member.

push_back works because nothing needs to be inserted, only a new value needs to be added to the end of the vector. If the vector needs to be reallocated, to accomodate its growth, that uses copy or move constructors, which are still valid for a std::pair with a const value.

like image 71
Sam Varshavchik Avatar answered Feb 15 '23 03:02

Sam Varshavchik