C++ Logo

STD-PROPOSALS

Advanced search

Subject: Re: [std-proposals] Proposal of constpub (DRAFT 1)
From: jianping z (zjpwork_at_[hidden])
Date: 2020-01-13 21:39:55


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]
> <mailto: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 list run by std-proposals-owner@lists.isocpp.org

Standard Proposals Archives on Google Groups