Please find attached a 2-page draft proposal entitled:
Proposal of constpub
It seems a little thing but easy to implement and I think it may have broad appeal.
Anyway, initial thoughts appreciated.
-Andrew.
Interesting...
From the paper:
struct S {
constpub int i;
void f() {
std::cout << i; // OK: private read
i = 42; // OK: private write
}
};
int main() {
S s;
std::cout << s.i; // OK: public read
s.i = 42; // ERROR: public write
}
This is an extremely common thing to want to do.
You've stated correctly in the paper that the common way to handle this is to provide a public read-only accessor function.
There's another way to handle it, though: you could use a constexpr reference:
struct S {
constexpr const int& i = private_i;
void f() {
std::cout << private_i << '\n'; // OK: private read
private_i = 42; // OK: private write
}
private:
int private_i;
};
int main() {
S s{};
s.f();
std::cout << s.i << '\n'; // OK: public read
s.i = 42; // ERROR: public write
s.private_i = 42; // ERROR: public access to private var
}
Now, there's three problems with this:
1) The standard does not allow non-static data members to be declared constexpr.
2) If you remove the constexpr, this all works but the reference now consumes memory in the struct.
3) If the struct is copied, the reference is also copied, and so the reference now refers to the original struct.
But (1) Isn't just bad news: it's also good news. It means that in a future C++, we could allow programmers to declare a constexpr member that was a reference, that satisfied our needs: always referring to what it said it referred to, no matter if a copy happened or not, and it would be backwards-compatible with existing code.
It doesn't 100% satisfy what you're looking for, since the private member and the public member would have different names, but I assume that would be OK with you.
Regarding "this is an extremely common thing to want to do", that's absolutely true for me, because we often want to migrating existing code. For example, we might want an associative container whose elements have two members: "key" and "value". But for compatibility, we might also want to refer to them as "first" and "second".
And on a related note, while I might want my container code to be able to access "key' and "value" in a mutable way, I might want my users to have read/write access to "value", but be limited to read-only access to "key".
-- Jorg