Date: Sun, 26 Apr 2026 08:12:18 +0200
There is no ‘unit file’ in C++. This means that any file could just introduce their own “helper” function (“helper” meaning that we want to access something from the outside we are not supposed to access). However, C++ always requires the header file anyway and this can obviously be edited. Everyone can just change ‘private’ to ‘public’ (though there are some theoretical limitations because of ordering guarantees which would not work with existing compiled libraries according to the standard) or introduce a friend function. We just usually don’t do this with the STL or some other external library. However, with your proposed solution we could easily extend any class or access private members from any file. Especially when updating external libraries this modification would now persist whereas changing the header file needs to be repeated. We should not make it this easy.
However, this brought me to a different idea: In theory we got modules in C++. Maybe it would make sense to allow helper functions inside the module (as long as they are not exported). So, we might have visibility ’module’ for member variables. I guess, we still need to differentiate between ‘private’ and ‘protected’ visibility. This would require ‘module private’ or ‘module protected’. This would reuse an existing keyword. I suspect that this ordering of the keywords is harder to parse and we might just want the order ‘private module’ and ‘protected module’. The meaning of this would be that every freestanding function inside the same module as the class which is not exported by the module can access these members.
I just came up with yet another idea that can help with hiding the private implementation (at least a little bit):
class Foo_helper
{
protected:
void helper(auto this self);
}
class Foo : Foo_helper
{
…
}
This is using ‘deducing this’ inside a helper class. Though, now that I’m thinking about this, I’m not entirely sure if we would need to make Foo_helper a friend of Foo to allow it to access private and protected members of Foo. Other than that, notice that private inheritance also makes the members of Foo_helper private inside Foo. Additionally, with the use of #ifdefs we might be able to provide an empty class declaration for Foo_helper inside the header file and a different one inside the unit file (including the header after defining Foo_helper). This could truly hide the private interface. But, it is only useful if we don’t need to make Foo_helper a friend of Foo.
One problem you might not have thought about is that just declaring private void Foo::helper() inside the unit file without having it inside the class declaration is that you need to properly order your helper functions so that they can call each other. Or we introduce that we can first declare them in the unit file (most likely at the top right after the include of the header) and then later define them.
On Apr 25, 2026, at 10:57 PM, Steve Weinrich via Std-Proposals <std-proposals_at_[hidden]> wrote:
I may have missed something, but one can declare:class Foo{friend class Helper;friend void FooHelper (Foo *);};Both the class Helper and the function FooHelper() can access all private members of Foo. Thus, only the names and/or the function signature is declared in the interface.--On Sat, Apr 25, 2026, 14:46 André Offringa via Std-Proposals <std-proposals_at_[hidden]> wrote:Hi all,
I was wondering what people think of the following idea. The problem I'm
trying to address is that if we want to introduce a helper method for a
class, we have to declare this helper function in the class, e.g. assume
this situation:
== Header file: ==
class Foo {
public:
void A();
private:
void Helper();
int value_;
};
== Unit file: ==
void Foo::A() {
...
Helper();
...
}
void Foo::Helper() {
...
value_ = ...;
...
}
I think it would be useful if there would be a way to skip the
declaration of the Helper method inside the class (in the header file),
and make it translation local just like a static function or function
inside an anonymous namespace would be. From the compiler's point of
view, it could then act as a translation-unit-local function, except
with the possibility to access (private) class fields.
The benefit is that the method is no longer part of the "interface" of
the class, and this is useful because it is, after all, an
implementation detail of the class. This makes it also no longer
necessary to have the parameter types and return value type declared in
the header file, which decreases dependencies between files.
An example of how this could look like, could be to use the keyword
'private' and let it act as an identifier for declaring such a function,
e.g.:
== Header file: ==
class Foo {
public:
void A();
private:
int value_;
}
== Unit file: ==
private void Foo::Helper() {
...
value_ = ...;
...
}
void Foo::A() {
...
Helper();
...
}
Of course the syntax is open for discussion. The idea is that Helper()
is now a private translation-unit-local function that receives the
'this' pointer and access to private fields. The function itself acts in
name lookup as a free function, to avoid participating in member lookup,
but is only visible inside class member functions or other private
translation-unit-local functions, and is not accessible outside of that.
This makes it somewhat between a member function and a free function.
With such an approach, it can not be used to access private fields from
a scope that does not allow access to those fields. Hence, the class
data remains encapsulated. It should not modify the layout of the class
and not change its ABI. There are more details to think through.
Thinking of alternatives, another direction to solve this would be to
change the standard such that friend functions can be declared as friend
outside of the class definition, instead of by introducing a function
with special visibility rules. They would then behave as normal
functions, which simplify some details. This makes private data too
widely usable, so I don't see a good solution in that direction.
Syntax aside, the problem I'm trying to solve is to have a function that:
- has access to private members
- is defined only in the unit file
- does not require any declaration in the header
- does not become part of the class interface
I think the best existing alternative for this situation is to declare a
static free function in the unit file that takes as parameter the class
members it needs. In complex situations, this is not as nice. In pimpl
implementations it is a reasonable solution, but a pimpl pattern is not
always desired.
I'm curious to hear what people think about the idea of private
translation-unit-local functions.
Kind regards,
André Offringa
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Std-Proposals mailing list
Std-Proposals_at_[hidden]
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2026-04-26 06:12:34
