Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Assignment Operator implicitly deleted for const-members in c++? [duplicate]

This is not a duplicate of the question attached to the close request.

I have a class with a const-qualified field. I'm trying to assign it to a data structure that already has a value in the place I'm assigning. But because my class has a const-qualified field, my compiler is not allowing me to do so.


Errors:

Depending on the compiler, I either get:

note: copy assignment operator of 'A' is implicitly deleted because field 'size' is of const-qualified type 'const unsigned short'

or:

error: non-static const member ‘const short unsigned int A::size’, cannot use default assignment operator

Which are basically the same thing.


Minimal Viable Example:

#include <iostream>
#include <vector>
class A {
    private:
        const unsigned short size;
     
    public:
    
        A(unsigned short sz) : size(sz) {}
        
        void print_sz() {
            std::cout<<this->size<<"\n";
        }
};

int main()
{
    A a = A(2);
    
    std::vector<A> a_vec = std::vector<A>();
    a_vec.push_back(A(0));
    a_vec[0] = A(1); // This line breaks my code
    
    a_vec[0].print_sz(); // I want to see 1 printed here
    return 0;
}

This doesn't make sense to me... why can't it implicitly copy over a const value?

Who cares if it's const, just make a copy of the damn short!

I've tried std::move and so many other things

I don't want to implement a copy assignment operator and copy each member by hand because there's so many fields and a dynamic array in my actual code that I know I'll mess something up if I try to implement it.

I just want to put an A into my vector...


Questions:

1 - How do I fix this? I want any quick hack that works and doesn't require implementing a copy assignment operator. I don't care about the element already in the container. I just want to move the data from the temporary stack into the vector (to use elsewhere)

2 - If you have the time, I'd love an explanation as to why this makes sense...


Thanks.

like image 565
QuantumHoneybees Avatar asked Sep 03 '25 16:09

QuantumHoneybees


2 Answers

You can't do assignment here. You've specified that size is const, which means you can initialize it, but you can't assign to it.

One (kind of ugly) workaround would be to destroy the existing object, then use placement new to create a new object with the new value in the same location.

#include <iostream>
#include <vector>
class A {
    private:
        const unsigned short size;
     
    public:
    
        A(unsigned short sz) : size(sz) {}
        
        void print_sz() {
            std::cout<<this->size<<"\n";
        }
};

int main()
{
    A a = A(2);
    
    std::vector<A> a_vec = std::vector<A>();
    a_vec.push_back(A(0));
    a_vec[0].~A();        // out with the old
    new (&a_vec[0]) A(1); // and in with the new
    
    a_vec[0].print_sz(); // Prints `1`
    return 0;
}
like image 167
Jerry Coffin Avatar answered Sep 05 '25 08:09

Jerry Coffin


The assignment operator= is deleted because by default it just assigns to each member of the class. But since a const variable cannot be assigned to, there is no point in having the implicit assignment operator. This goes for both copy assignment as well as move assignment.

like image 32
Anoop Rana Avatar answered Sep 05 '25 08:09

Anoop Rana