<div dir="auto"><div><br><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Mon, 27 Apr 2026, 08:21 André Offringa via Std-Proposals, &lt;<a href="mailto:std-proposals@lists.isocpp.org">std-proposals@lists.isocpp.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>

  
    
  
  <div>
    <p>Hi Steve,</p>
    <p>Thanks for the feedback. You&#39;re suggesting helper friend classes
      as an alternative, but there are some issues with a helper friend
      class to enable translation-unit-local functions. First of all, to
      make the functions translation-unit-local, it must be placed in an
      anonymous namespace. To do this, it must be done so before the
      befriending, so something like this:</p>
    <p>== header file ==</p>
    <p>namespace {<br>
      struct FooFriend;<br>
      }<br>
      <br>
      class Foo {<br>
        int a;<br>
        friend FooFriend;<br>
      };</p>
    <p>== cpp file ==</p>
    <p>namespace {<br>
      struct FooFriend {<br>
        static void SetA(Foo&amp; foo) {<br>
          foo.a = 3;<br>
        }<br>
      };<br>
      }<br>
      <br>
    </p>
    <p>I think this is an awkward construct. The Google C++ style
      explicitly forbids this, as it doesn&#39;t allow unnamed namespaces in
      header files. </p></div></blockquote></div></div><div dir="auto">It breaks the ODR. The friend declaration refers to a different FooFriend in each translation unit.</div><div dir="auto"><br></div><div dir="auto">So the FooFriend solution doesn&#39;t mix well with the desire to have internal linkage for all the helpers.</div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote gmail_quote_container"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><p>The SetA() function is also now publicly available,
      and even though that is limited to a single translation unit, it
      is still easy to accidentally break a class invariant in this way.
      The classname of FooFriend is leaked out of the scope of the unit
      file (style guides often mandate to put it in yet another
      subnamespace like &#39;details&#39; in that case). Finally, the syntax of
      the call and use of private variables is more verbose. Compare it
      to:</p>
    <p>== header file ==<br>
      <br>
      class Foo {<br>
        int a;<br>
      };<br>
      <br>
      == cpp file ==<br>
      <br>
      private Foo::SetA() {<br>
        a = 3;<br>
      }</p>
    <p><br>
    </p>
    <p>So, while there are alternatives for private functions, I don&#39;t
      think the friend classes are really a solution for the issue that
      the proposal tries to solve.</p>
    <p>Kind regards,<br>
      André</p>
    <div>On 4/26/26 11:05 PM, Steve Weinrich via
      Std-Proposals wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="auto">This is purely subjective, but I don&#39;t find that a
        single line, &quot;friend class Helper;&quot; is clutter.  It can be put
        at the very bottom of the class.  It gives Helper full access
        for whatever purpose.  No committee required!
        <div dir="auto"><br>
        </div>
        <div dir="auto">Cheers,</div>
        <div dir="auto">Steve</div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Sun, Apr 26, 2026, 00:17
          André Offringa via Std-Proposals &lt;<a href="mailto:std-proposals@lists.isocpp.org" target="_blank" rel="noreferrer">std-proposals@lists.isocpp.org</a>&gt;
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div>
            <div>On 4/25/26 10:56 PM, Steve Weinrich via Std-Proposals
              wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="auto">I may have missed something,  but one can
                declare:
                <div dir="auto"><br>
                </div>
                <div dir="auto">class Foo</div>
                <div dir="auto">{</div>
                <div dir="auto">  friend class Helper;</div>
                <div dir="auto"><br>
                </div>
                <div dir="auto">  friend void FooHelper (Foo *);</div>
                <div dir="auto">};</div>
                <div dir="auto"><br>
                </div>
                <div dir="auto">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.</div>
              </div>
            </blockquote>
            <p><br>
            </p>
            <p>What I&#39;m trying to solve:</p>
            <p>- Wen using friend declarations, these clutters the class
              with implementation details that do not affect the layout
              of the class.</p>
            <p>- For FooHelper(), it would require the return and
              parameters types to be available at the place of the
              friend declaration, creating extra dependencies. Your
              example takes only Foo*, but I think it&#39;s common for a
              helper function to use other parameters (and/or have a
              return value), which causes the dependencies.</p>
            Regards,<br>
            André
            <p><br>
            </p>
            <blockquote type="cite"><br>
              <div class="gmail_quote">
                <div dir="ltr" class="gmail_attr">On Sat, Apr 25, 2026,
                  14:46 André Offringa via Std-Proposals &lt;<a href="mailto:std-proposals@lists.isocpp.org" rel="noreferrer noreferrer" target="_blank">std-proposals@lists.isocpp.org</a>&gt;
                  wrote:<br>
                </div>
                <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi
                  all,<br>
                  <br>
                  I was wondering what people think of the following
                  idea. The problem I&#39;m <br>
                  trying to address is that if we want to introduce a
                  helper method for a <br>
                  class, we have to declare this helper function in the
                  class, e.g. assume <br>
                  this situation:<br>
                  <br>
                  == Header file: ==<br>
                  <br>
                  class Foo {<br>
                  public:<br>
                     void A();<br>
                  <br>
                  private:<br>
                     void Helper();<br>
                  <br>
                     int value_;<br>
                  };<br>
                  <br>
                  == Unit file: ==<br>
                  <br>
                  void Foo::A() {<br>
                     ...<br>
                     Helper();<br>
                     ...<br>
                  }<br>
                  <br>
                  void Foo::Helper() {<br>
                     ...<br>
                     value_ = ...;<br>
                     ...<br>
                  }<br>
                  <br>
                  I think it would be useful if there would be a way to
                  skip the <br>
                  declaration of the Helper method inside the class (in
                  the header file), <br>
                  and make it translation local just like a static
                  function or function <br>
                  inside an anonymous namespace would be. From the
                  compiler&#39;s point of <br>
                  view, it could then act as a translation-unit-local
                  function, except <br>
                  with the possibility to access (private) class fields.<br>
                  <br>
                  The benefit is that the method is no longer part of
                  the &quot;interface&quot; of <br>
                  the class, and this is useful because it is, after
                  all, an <br>
                  implementation detail of the class. This makes it also
                  no longer <br>
                  necessary to have the parameter types and return value
                  type declared in <br>
                  the header file, which decreases dependencies between
                  files.<br>
                  <br>
                  An example of how this could look like, could be to
                  use the keyword <br>
                  &#39;private&#39; and let it act as an identifier for
                  declaring such a function, <br>
                  e.g.:<br>
                  <br>
                  == Header file: ==<br>
                  <br>
                  class Foo {<br>
                  public:<br>
                     void A();<br>
                  <br>
                  private:<br>
                     int value_;<br>
                  }<br>
                  <br>
                  == Unit file: ==<br>
                  <br>
                  private void Foo::Helper() {<br>
                     ...<br>
                     value_ = ...;<br>
                     ...<br>
                  }<br>
                  <br>
                  void Foo::A() {<br>
                     ...<br>
                     Helper();<br>
                     ...<br>
                  }<br>
                  <br>
                  Of course the syntax is open for discussion. The idea
                  is that Helper() <br>
                  is now a private translation-unit-local function that
                  receives the <br>
                  &#39;this&#39; pointer and access to private fields. The
                  function itself acts in <br>
                  name lookup as a free function, to avoid participating
                  in member lookup, <br>
                  but is only visible inside class member functions or
                  other private <br>
                  translation-unit-local functions, and is not
                  accessible outside of that. <br>
                  This makes it somewhat between a member function and a
                  free function. <br>
                  With such an approach, it can not be used to access
                  private fields from <br>
                  a scope that does not allow access to those fields.
                  Hence, the class <br>
                  data remains encapsulated. It should not modify the
                  layout of the class <br>
                  and not change its ABI. There are more details to
                  think through.<br>
                  <br>
                  Thinking of alternatives, another direction to solve
                  this would be to <br>
                  change the standard such that friend functions can be
                  declared as friend <br>
                  outside of the class definition, instead of by
                  introducing a function <br>
                  with special visibility rules. They would then behave
                  as normal <br>
                  functions, which simplify some details. This makes
                  private data too <br>
                  widely usable, so I don&#39;t see a good solution in that
                  direction.<br>
                  <br>
                  Syntax aside, the problem I&#39;m trying to solve is to
                  have a function that:<br>
                  - has access to private members<br>
                  - is defined only in the unit file<br>
                  - does not require any declaration in the header<br>
                  - does not become part of the class interface<br>
                  <br>
                  I think the best existing alternative for this
                  situation is to declare a <br>
                  static free function in the unit file that takes as
                  parameter the class <br>
                  members it needs. In complex situations, this is not
                  as nice. In pimpl <br>
                  implementations it is a reasonable solution, but a
                  pimpl pattern is not <br>
                  always desired.<br>
                  <br>
                  I&#39;m curious to hear what people think about the idea
                  of private <br>
                  translation-unit-local functions.<br>
                  <br>
                  Kind regards,<br>
                  André Offringa<br>
                  <br>
                  -- <br>
                  Std-Proposals mailing list<br>
                  <a href="mailto:Std-Proposals@lists.isocpp.org" rel="noreferrer noreferrer noreferrer" target="_blank">Std-Proposals@lists.isocpp.org</a><br>
                  <a href="https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals" rel="noreferrer noreferrer noreferrer noreferrer" target="_blank">https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals</a><br>
                </blockquote>
              </div>
              <br>
              <fieldset></fieldset>
            </blockquote>
          </div>
          -- <br>
          Std-Proposals mailing list<br>
          <a href="mailto:Std-Proposals@lists.isocpp.org" rel="noreferrer noreferrer" target="_blank">Std-Proposals@lists.isocpp.org</a><br>
          <a href="https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals" rel="noreferrer noreferrer noreferrer" target="_blank">https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals</a><br>
        </blockquote>
      </div>
      <br>
      <fieldset></fieldset>
    </blockquote>
  </div>

-- <br>
Std-Proposals mailing list<br>
<a href="mailto:Std-Proposals@lists.isocpp.org" target="_blank" rel="noreferrer">Std-Proposals@lists.isocpp.org</a><br>
<a href="https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals" rel="noreferrer noreferrer" target="_blank">https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals</a><br>
</blockquote></div></div></div>

