SamVanDonut
SamVanDonut

Reputation: 369

Cheating constness?

I found the curious (to me at least) behavior that, in the following code, the function B::Compute() const modifies a non-const member. I thought this was not allowed, especially since I did not intend to cheat constness, e.g. via const_cast or alike. Nevertheless, the code compiles (see details below). Why is this the case?

#include <vector>
#include <iostream>

class A {
    std::vector<int> v_;
public: 
    void AddToA( int const e ) {
        v_.push_back( e );
    }

    void Print() const { 
        for( auto const& v : v_ ) {
            std::cout << v << "\t";
        }
        std::cout << "\n";
    }
};

class B {
    A & a_;
public:  
    void Compute() const {
        a_.AddToA( 1 );
    }
};
int main() {
    A a = A(); 
    B b = B( a );

    B b2 = B( a );

    b.Compute();
    a.Print();

    b2.Compute();
    a.Print();

    return 0;
}

Edit:

As pointed out to me, my compilation details were nonsense. Hence, I deleted them.

Upvotes: 0

Views: 100

Answers (1)

Sneftel
Sneftel

Reputation: 41464

It's legal to modify the object that a_ references from within b.Compute(), because you're not modifying a_. Making a member function const means that you can't modify the values stored in the member variables, but that's already impossible with references (which can never be changed to reference new objects).

Your failure to compile without the C++17 flag has nothing to do with constness. Read the error messages; they're telling you that you're trying to invoke the deleted move/copy constructors from your InstantiateA() function, which is not allowed without the delayed materialization feature of C++17.

You would likely have learned all this yourself if you had bothered to put together a minimal example.

Upvotes: 4

Related Questions