C++ Logo

std-proposals

Advanced search

Re: Proposal of constpub (DRAFT 1)

From: connor horman <chorman64_at_[hidden]>
Date: Mon, 13 Jan 2020 23:06:48 -0500
I’d recommend having read/write properties return a reference, and
potentially having read properties return a const reference, and otherwise
be similar to methods (cv-qualifiers, ref-qualifiers, etc)

On Mon, Jan 13, 2020 at 22:40 jianping z via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Hi all,
>
> if we have to add a new keyword (i.e. constpub) to make something like
> this special case to work, I would suggest to add a keyword "property" to
> allow special functions to be called using its name as variable for
> assignment syntax.
>
> //a.hpp
> class A
> {
> public:
> //read/write properties, have additional protection than using "value"
> directly
> property int v() { return value; } //read
> property
> property int v(int val) { value=val; return value; } //write
> property, return type and param type don't need to match
> property int v(short val) { value=val; return value; } //write
> property, overload allowed, as long as it doesn't conflict with others
>
> //read only property, no write property defined
> property int& v_readonly() { return value_readonly; } //can return
> reference to variable
>
> //write only property, no read property defined
> property void v_writeonly(int val) { value_writeonly=val; } //return
> type can be void
>
> //static read only property, static
> property static int v_static() { return value_static; }
>
> protected:
> //protected property for use by inherited class
> property int v_protected() { return value_protected; }
> //read property
> property void v_protected(const int& val) { value_protected=val; }
> //write property, return type can be void
>
> private:
> int value;
> int value_readonly;
> int value_writeonly;
> int value_protected;
> static int value_static;
> }
>
> //main.cpp
> #include "a.hpp"
> int main()
> {
> int v=5;
> A a{};
> a.v=v+1; //ok
> v=a.v; //ok
>
> v=a.v_readonly; //ok
> a.v_readonly=v; //error, not defined
>
> a.v_writeonly=v; //ok;
> v=a.v_writeonly; //error, not defined
>
> v=a.v_static; //ok
> a.v_static=v; //error, not defined
>
> a.v_protected=v; //error, protected for inherited class
> v=a.v_protected; //error, protected for inherited class
> }
>
> though it still use private variable, but property is more useful than
> bare "constpub" variable.
>
> Thanks,
>
> Jianping
>
>
> On 1/10/2020 08:46 PM, Jorg Brown via Std-Proposals wrote:
>
> On Thu, Nov 21, 2019 at 2:34 AM Andrew Tomazos via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> 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:
>
> For example:
>
>
>> 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
> }
>
> Obligatory godbolt reference: https://godbolt.org/z/7ieE4h
>
> 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
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2020-01-13 22:09:32