C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Translation-unit-local functions that access private class fields

From: André Offringa <offringa_at_[hidden]>
Date: Wed, 29 Apr 2026 15:48:30 +0200
On 4/29/26 00:44, Arthur O'Dwyer wrote:
> On Tue, Apr 28, 2026 at 4:48 PM André Offringa via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>
> Hi all,
>
> In follow-up on the discussion about private extension methods, I
> updated the original draft from 2013 with results from discussion
> then
> and now and placed it here:
>
> https://github.com/aroffringa/stdcxx-privext-2026/blob/main/proposal/draft.md
>
>
> You say "based on an earlier proposal from 2013 by Matthew
> Fioravante," but I don't see where you actually link to that earlier
> proposal. You should do that.

Fair enough. The git repo contains the license — I've added links to
Matthew's proposal now inside the proposal as well.

> You say "Large parts of his text were reused, following the MIT
> license," but on the one hand I'm sure you're not following the letter
> of the MIT license <https://mit-license.org/> (since I don't see those
> letters anywhere in your text), and meanwhile since you don't provide
> a pointer to the original I would say you're not following the spirit,
> either. (I don't think the MIT license really applies to non-software
> anyway.)

The license file is in the repo,
https://github.com/aroffringa/stdcxx-privext-2026 . I've added a link to
it in the document.

> You have a "References" section. That's (one of) the places I'd expect
> to see a link to the prior art you're talking about.
> You have a "Changes compared to the 2013 proposal." That's a place I'd
> /*definitely*/ expect to see a link to the 2013 proposal.

Good points, links were added.

>
> "We will perform...", "Let us examine..." — I recommend to cut the
> cruft and just say what you're proposing, and why. Partly I'm grumpy
> because of how that useless 14-row table rendered on mobile; but even
> if I weren't grumpy, I don't think the proposal benefits from that
> 14-row table.

I'd agree the table is not super useful -- table removed, I surely don't
want to make people grumpy ;).

>
> You use the acronyms "PEM" and "PSEMF". Try not to need them: write
> out what you mean. If you /must/ acronymize, be consistent — these are
> either "M"embers or "M"ember "F"unctions — pick one!

Changed to consistently use 'member functions' (what previously was
called 'methods'). The abbreviations are quite useful in code examples.

>
> If we allow the implementor to add private member functions via
> private void Foo::newfunc() { }
> private static void Foo::newfunc() { }
> then should we also allow the implementor to add private static data
> members via
> private static int Foo::sdm = 42;
> ? (Incidentally, this shows that your 14-row table is missing a bunch
> of rows.)

Agree. The now-removed table actually also misses aliases (which is not
unimportant when discussing the syntax of reopening the class vs use of
private before function definition).

I’ve considered whether to generalize this to broader class extensions
or whether the focus should be on solving the issue of private member
functions. Private static data members are indeed also not part of the
interface and could be extended. The same holds for private type aliases.

However, my preference is to focus only on private member functions. I
think they would be the most commonly used and imho most beneficial
option to have. There are relatively simple alternatives for static data
members (for example, one could just start a new class inside the
implementation file), as well as for type aliases (just define them
locally). This is not the case for private member functions (with
internal linkage). I think there are more arguments, and I've summarized
those now in a new section under "Private static data members and
private aliases" in the draft.

>
> Can the implementor's "private extensions" include declarations, or
> just definitions? That is, is this permitted?
> struct S { };
> private int S::f(int x = 0);
> private int S::f(int x) { return x; }
> I would think that it should be.

This was indeed not covered in the proposal, but is indeed a good
addition. I think it should indeed be allowed, so that there's more
flexibility in where the private extension member functions are defined.
I've added a section to the proposal mentioning it.

>
> "Note that we cannot declare private extension default constructors,
> copy constructors, ..." — What do you mean "note"? You didn't mention
> any of this before! And why can't we? This part can't just be a
> throwaway line as if it's obvious from context; you actually need to
> explain what you're talking about here.

Fair enough, I've added some motivation.

> And what about comparison operators?

Other properties of PEMFs mentions that operator overloading is allowed
(I at least don't see why not). The syntax seems trivial enough to me to
not need an example.

> Swap?

There's nothing special about swap functions, is there?

> Conversion functions of the form `private S::operator T() const`?

This appears to not lead to issues; I’ve clarified that it is permitted.

>
> Much of the confusion in your paper could be avoided if you'd just try
> to write some "Proposed Wording." Figure out what sections of the
> Standard would have to change, and show how.
> Look at existing proposals to see how "Proposed Wording" is supposed
> to be formatted.

Agreed. The design of the feature is slowly settling, so I'll start
working on a drafting such a section.

Thanks for the useful comments,

Regards,
André

Received on 2026-04-29 13:48:36