Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vector of pair with const member

As stated in this answer a std::vector<T> cannot contain const T, or classes with const-members. However, this is not the case when T = std::pair<const int, int>, as shown below. Why is this the case? How is std::pair special?

#include <utility>
#include <vector>

struct foo
{
    const int first;
    int second;
};

int main() {
    std::vector<std::pair<const int, int>> V1;
    V1.resize(3); // This compiles

    std::vector<foo> V2;
    V2.resize(3); // This gives the error listed below
}

error: use of deleted function 'foo::foo()'

note: 'foo::foo()' is implicitly deleted because the default definition would be ill-formed:

like image 726
Jonas Avatar asked Mar 18 '19 09:03

Jonas


People also ask

Can a pair contain a vector?

A pair is a container which stores two values mapped to each other, and a vector containing multiple number of such pairs is called a vector of pairs.

What is a const vector?

A const vector will return a const reference to its elements via the [] operator . In the first case, you cannot change the value of a const int&. In the second case, you cannot change the value of a reference to a constant pointer, but you can change the value the pointer is pointed to.

Can you modify const vector in C++?

A const iterator points to an element of constant type which means the element which is being pointed to by a const_iterator can't be modified.

How do you add a vector to a pair?

The standard solution to add a new std::pair to a vector of pairs is using the std::emplace_back(T&&... args) function, which in-place construct and insert a pair at the end of a vector, using the specified arguments for its constructor. Note that this function is added in C++11.


1 Answers

You are mixing two things here. The error that you get is due to the implicitly deleted foo() default constructor that std::vector::resize(size_type count) invokes:

If the current size is less than count,
1) additional default-inserted elements are appended

The std::pair template has a default constructor, this is why the call to V1.resize succeeds. If you provide one for foo as well, or allow its implicit generation by in class initialization, e.g.

struct foo
{
    const int first = 42;
    int second = 43;
};

then

std::vector<foo> V2;
V2.resize(3);

will happily compile. The operation that won't work out for both std::pair<const int, int> and foo is assignment. This won't compile:

V1[0] = std::pair<const int, int>(42, 43); // No way
V2[0] = { 42, 43 }; // Also not ok, can't assign to const data member

which doesn't have anything to do with std::vector, but with the const-qualified data members in both cases.

like image 92
lubgr Avatar answered Oct 05 '22 18:10

lubgr