C++ Logo

std-proposals

Advanced search

Re: Proposal of constpub (DRAFT 1)

From: jianping z <zjpwork_at_[hidden]>
Date: Mon, 13 Jan 2020 20:39:55 -0700
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
>


Received on 2020-01-13 21:42:29