C++ Logo

std-proposals

Advanced search

Re: [std-proposals] New access specifiers

From: Paul Meckel <paul_meckel_at_[hidden]>
Date: Mon, 16 Dec 2024 20:24:03 +0100
I like the java syntax also. it is concise. Though I am concerned about
adding two new keywords to the language that are not too uncommon
otherwise and not reserved either and which may lead to naming
collisions (particularly with std::set).

I am also concerned about hiding the abstraction. With a function call
it is explicit that it might do something in addition to simply setting
the value. Then again the same concept of using the direct access syntax
for function calls in disguise is also used in other languages, such as C#.

Then there are additional questions, such as, should getters be required
to be const? what about getters to references?

I like the idea of defining the functions anyway. Perhaps maybe use an
attribute, such as `[[set(&C::complicated)]]`, with an implied type of
`void (C::*)(T)` where T is the type of the member variable.

```cpp
class C
{
   private:
     [[set(public default), get(public default)]] int trivial{99}; //
maybe something like that for trivial types?
[[set(&C::set_complicated), get(&C::get_complicated)]] int
complicated{42}; // and specifying the member function pointers for more
involved functions.
   protected:
     void set_complicated(int value) noexcept { this->complicated =
std::max(value, 42); }
   public:
     [[nodiscard]] int get_complicated() const noexcept { return
std::abs(complicated); }
};
```

On 16.12.24 17:01, Jeremy Rifkin via Std-Proposals wrote:
>> I genuinely think this would be something useful
> Fwiw, I think it could be useful too but a lot of justification will
> need to be given as to why it's useful enough to warrant such a change
> to the core language. I'm not convinced it's not an anti-pattern.
>
>> so you also have extra parentheses get_variableName() which looks like a normal function call at first glance
> Well, yes, it is a normal function call and that's ok. You're
> explicitly requesting access to a given internal property. I think
> there's actually some value in this explicitness.
>
>> you need to write at least 1 extra line for each member variable and this is another chance to make mistakes
> As I mentioned earlier, this is solved with tooling. Clion can
> automatically generate getters and setters and I'm sure other IDEs can
> too.
>
> If you don't like the extra parentheses, my two cents would be to
> consider something like JavaScript's getters which let you do
> something like
>
> class C {
> constructor() {
> this.items = [];
> }
> add_item(item) {
> this.items.push(item);
> }
> get last() {
> return this.items[this.items.length - 1];
> }
> }
>
> const c = new C();
> c.add_item(1);
> c.add_item(2);
> console.log(c.last); // prints 2
>
> There's a similar syntax for setters. I've found these really nice to
> work with and they allow for some nice expressive code.
>
> Cheers,
> Jeremy
>
> On Mon, Dec 16, 2024 at 10:41 AM James via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>> I can see people's concern about this, but I genuinely think this would be something useful. At least to me. Particularly, I like being able to use the variable name itself, instead of get_variableName. Remember also one is direct access and the other is function call, so you also have extra parentheses get_variableName() which looks like a normal function call at first glance.
>> The original example I showed might not look like much, but when you have more member variables that have the same requirements, you need to write at least 1 extra line for each member variable and this is another chance to make mistakes.
>> Sure reflection solves that, but to be fair: I don't see reflection happening for quite some time and still, I think an access specifier is much better. Also consider parsing/understanding extra code as a human versus parsing a single access specifier. Even reflection has to add some overhead in terms of code size and it's likely much bigger than a single keyword.
>>
>> In terms of implementation, I don't think something like this would take a lot to implement. I just don't think it's good enough to go with it as is. So, don't get me wrong, but I think we heard enough skepticism and no improvement ideas. Of course you are free to do/say whatever, but I'd like to see some ideas around this please.
>> I think Herb would like something like this :D ("expressing more with less code", I think he said)
>>
>> One thing I'm not sure about, what happens to member functions? Because normally specifiers would affect them too
>>
>> On Mon, Dec 16, 2024 at 8:07 AM James <james.business.84_at_gmail.com> wrote:
>>> In C++, it’s common to encounter situations where a member variable needs to be fully controlled by its owner class but also readable from outside the class. The typical solution is to define a public getter for the variable:
>>> ```cpp
>>> class Foo
>>> {
>>> int value = 0;
>>> public:
>>> int get_value() const { return value; }
>>> };
>>> ```
>>>
>>> I propose two new access specifiers to make this process easier. First one is "exposed private". Member variables defined after this specifier would allow anyone to access these variables as const, but only owner class to modify them.
>>> The other specifier is "exposed protected", it's the same as before, but also allows derived classes to modify these variables.
>>>
>>> So previous code could just be rewritten as following:
>>> ```cpp
>>> class Foo
>>> {
>>> exposed private:
>>> int value = 0;
>>> };
>>> ```
>>>
>>> It's less boilerplate and you get to refer to the variable with its original name.
>>> ```cpp
>>> Foo foo;
>>> int value = foo.value; // ok
>>> foo.value = 15; // error, can't modify const variable
>>> ```
>>>
>>> Note: I'm not sure about naming and I'm open to ideas. Also the exact thing I just specified might contain issues, but you get the idea.
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2024-12-16 19:24:08