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