Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vector - swap two elements when elements have const members

I have the following code

class a {
public:
    const int aa;
    a(int aa) : aa(aa){}
};
int main() {
    std::vector<a> v;
    v.emplace_back(1);
    v.emplace_back(2);
    v.emplace_back(3);
    v.emplace_back(4);

    std::iter_swap(v.begin() + 1, v.rbegin());

    system("pause");
    return 0;
}

I get an error when I try to swap two elements of the vector.

Error   C2280   'a &a::operator =(const a &)': attempting to reference a deleted function

I understand it's because a has a constant member, but I am not able to figure out how to get this to work.

like image 661
MichaelMitchell Avatar asked Aug 31 '16 09:08

MichaelMitchell


People also ask

How do you swap two values in a vector?

The std::vector::swap() function is used to swap the entire contents of one vector with another vector of same type. If std::swap() function is used for swapping two vectors A and B, it will call specialized std::swap algorithm for std::vector which in turn calls A. swap(B) and swaps the contents.

Can a const vector be modified?

Yes, because std::vector is a value-type rather than a reference type. To simplify things: An std::vector considers the values in its buffer as part of itself, so that changing them means changing the vector.

Can you add to a const vector?

You can't put items into a const vector, the vectors state is the items it holds, and adding items to the vector modifies that state. If you want to append to a vector you must take in a non const ref. Save this answer.

Does vector have a swap function?

vector::swap() This function is used to swap the contents of one vector with another vector of same type and sizes of vectors may differ.


2 Answers

The problem is that the swap changes the value of existing element. Since the elements are const, they cannot be changed hence the compiler error.

If you insist on const elements, your vector should be vector<a*> or event better vector<unique_ptr<a>>. This will allow you to swap elements without mutating the actual elements of a

like image 175
doron Avatar answered Sep 25 '22 14:09

doron


Based on this thread following works:

#include <vector>
#include <iostream>

class Foo {
public:
    const int value;
    Foo(const int &&from) : value(std::move(from)){}
    Foo(const Foo &&other) : value(std::move(other.value)){}
    Foo & operator=(Foo && source) {
        this -> ~ Foo ();
        new (this) Foo(std::move(source));
        return *this;
    }
};

int main() {
    std::vector<Foo> v;
    v.emplace_back(1);
    v.emplace_back(2);
    v.emplace_back(3);
    v.emplace_back(4);

    std::cout << (v.begin() + 1)->value << "," <<v.rbegin()->value << std::endl;
    std::iter_swap(v.begin() + 1, v.rbegin());
    std::cout << (v.begin() + 1)->value << "," <<v.rbegin()->value << std::endl;
    return 0;
}
like image 27
j2ko Avatar answered Sep 21 '22 14:09

j2ko