As far as I know, this seems to be impossible in a straightforward way. Making the member const makes it const for everyone. I would like to have a read-only property, but would like to avoid the typical "getter". I'd like const public, mutable private. Is this at all possible in C++?
Currently all I can think of is some trickery with templates and friend
. I'm investigating this now.
Might seem like a stupid question, but I have been surprised by answers here before.
A possible solution can be based on an inner class of which the outer one is a friend, like the following one:
struct S {
template<typename T>
class Prop {
friend struct S;
T t;
void operator=(T val) { t = val; }
public:
operator const T &() const { return t; }
};
void f() {
prop = 42;
}
Prop<int> prop;
};
int main() {
S s;
int i = s.prop;
//s.prop = 0;
s.f();
return i, 0;
}
As shown in the example, the class S
can modify the property from within its member functions (see S::f
). On the other side, the property cannot be modified in any other way but still read by means of the given operator that returns a const reference to the actual variable.
There seems to be another, more obvious solution: use a public const reference member, pointing to the private, mutable, member. live code here.
#include <iostream>
struct S {
private:
int member;
public:
const int& prop;
S() : member{42}, prop{member} {}
S(const S& s) : member{s.member}, prop{member} {}
S(S&& s) : member(s.member), prop{member} {}
S& operator=(const S& s) { member = s.member; return *this; }
S& operator=(S&& s) { member = s.member; return *this; }
void f() { member = 32; }
};
int main() {
using namespace std;
S s;
int i = s.prop;
cout << i << endl;
cout << s.prop << endl;
S s2{s};
// s.prop = 32; // ERROR: does not compile
s.f();
cout << s.prop << endl;
cout << s2.prop << endl;
s2.f();
S s3 = move(s2);
cout << s3.prop << endl;
S s4;
cout << s4.prop << endl;
s4 = s3;
cout << s4.prop << endl;
s4 = S{};
cout << s4.prop << endl;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With