Reputation: 369
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
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