1

I have an example_class with two constant fields. When I try to emplace an object of that class into a std::vector, I get various errors such as "error: object of type 'example_class' cannot be assigned because its copy assignment operator is implicitly deleted". Does anyone know what is going on here? If I remove the const in example class, the code compiles without problems.

#include <vector>
#include <iostream>

using namespace std;

class example_class {
    public:
    example_class(int v1, int v2) : val1(v1), val2(v2) {}

    private:
    const int val1, val2;
};

int main() {

    vector<example_class> *vec = new vector<example_class>();
    vec->emplace(vec->begin() + 1, 13131, 12313);

    return 0;
}
  • 3
    When `std::vector` needs additional space it needs to be able to move (or copy) the existing elements into the new space. It can't in this case because the class contains `const` values. See [Type requirements](https://en.cppreference.com/w/cpp/container/vector/resize) – Richard Critten May 31 '22 at 12:32
  • Unrelated, but `new` is totally useless here, `vector vec;` does the same. – Quimby May 31 '22 at 12:33
  • 2
    I *think* the `emplace` call uses the copy **assignment** operator, which can't really be implemented when there are `const` data members. – Adrian Mole May 31 '22 at 12:36
  • Thanks for all the comments. Does anyone know why it compiles successfully if I use ```emplace_back``` rather than ```emplace```? – Alexander Richter May 31 '22 at 12:43

1 Answers1

1

By trying to use the std::vector<T>::emplace in this case we get something like: error: use of deleted function ‘Foo& Foo::operator=(Foo&&)’ which follows from the fact that...

...if the required location (e.g. vec.begin()) has been occupied by an existing element, the inserted element is constructed at another location at first, and then move assigned into the required location - More here

The example_class cannot be move assigned due to presence of const data members.

You still can construct elements directly in the vec by making sure that you not trying to construct them in place of any already existing element - by using `emplace_back().

More importantly, note that in vec.begin()+1 you try to access beyond the currently allocated memory for the vec (which is empty, meaning vec.begin() == vec.end()). It's the same as assuming that subscripting an element after the end of a vector will add an element to it - which is wrong.

rawrex
  • 4,044
  • 2
  • 8
  • 24