Conversation
…tic members (boostorg#53) Alternative design to boostorg#120: six macros mirroring BOOST_OPENMETHOD and its overrider macros, but declaring static member functions instead of free ones. No implicit `this`, no receiver binding - dispatch is still entirely by the method's own virtual parameters. - BOOST_OPENMETHOD_MEM declares a method as a static member function of the class it's used in, overloadable exactly like a free method. Its tag is generated per-expansion rather than ID-derived, which is what makes the overload possible. - BOOST_OPENMETHOD_TYPE_MEM names a member method's core `method<>` type, since BOOST_OPENMETHOD_TYPE can't (it reconstructs the tag from ID alone). - BOOST_OPENMETHOD_OVERRIDE_MEM / _DECLARE_OVERRIDER_MEM / _DEFINE_OVERRIDER_MEM add an overrider, as a static member function, to either a free method or a member method (qualified as Class::method). Being a member gives it the same access to its class's private state as any other member, with no `friend` declaration. - BOOST_OPENMETHOD_OVERRIDER_MEM finds a member overrider's key (`fn`, `method_type`) from outside, for explicit calls and for `next`/`has_next` via the core API - not available by name inside a _MEM body the way they are in a free one's. No core.hpp changes: each overrider is registered through a per-overrider "key" struct holding a BOOST_FORCEINLINE trampoline, so override_aux/thunk/ validate_overrider_parameter all see an ordinary function pointer, unchanged. Verified on gcc, clang and MSVC, including private access, overloaded member methods, and next<> from a DECLARE/DEFINE-split body (self-referencing, easy to get backwards - documented prominently). Known limitation: a _MEM overrider's body and key-accessor are each named once, overloaded purely on (return type, parameters) - never on which method they override, since a qualified ID can't be pasted into a new declaration. At most one overrider of a given exact signature per class, regardless of method. doc/modules/ROOT/pages/friends.adoc is retitled "Members and Friends" in the nav and gains a _MEM tutorial before the existing `friend` content, which it supersedes for classes under the caller's control. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E53cDWKgiva4cfH48EtvMP
|
An automated preview of the documentation is available at https://122.openmethod.prtest3.cppalliance.org/libs/openmethod/doc/html/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-09-19 16:37:01 UTC |
…rence The page named the macros in plain code spans while every other page links them, so a reader had no way from the tutorial to the reference page that describes the arguments. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E53cDWKgiva4cfH48EtvMP
The `pay` example declared its first parameter `Employee&` and made Payroll derive from Employee so that each overrider could cast it back - which reads as if a payroll were a kind of employee, and put a `static_cast<Payroll&>` in front of every call to the private member the example exists to demonstrate. Declare the parameter `Payroll&` instead, over a forward declaration, exactly as the `friend` example further down the same page already does: only a reference appears in the parameter list, and Payroll is not dispatched on. The inheritance and all three casts go away, and the page's claim that the overriders "call it as an ordinary same-class private call" becomes literally true. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E53cDWKgiva4cfH48EtvMP
The page now covers both ways an overrider reaches a class's private state - being a member of it, and `friend` - so the file name names the subject rather than one of the two answers. The nav label and the `@see` link text are unchanged; only the path moves. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E53cDWKgiva4cfH48EtvMP
The tutorial referred to `ID`, and to `(Class, ID, PARAMETERS, RETURN)`, which are the reference pages' formal parameter names and are never introduced on the tutorial page itself. Describe the arguments by what they are instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E53cDWKgiva4cfH48EtvMP
3 tasks
…acros BOOST_OPENMETHOD and BOOST_OPENMETHOD_MEM take an optional registry after the return type. The macros that name an existing member method, or that declare an overrider, cannot use one: a member method's registry is fixed by the declaration that created it, and an overrider takes the registry of the method it overrides, which LOCATE_METHOD finds through a guide lookup that enable_guide_ignoring_registry makes registry-agnostic. Passing one anyway produced two different failures, neither legible. BOOST_OPENMETHOD_TYPE_MEM accepted it and silently ignored it, because va_args<...>::return_type takes the first argument and drops the rest. The four overrider macros pasted __VA_ARGS__ raw into a function pointer type, which gave three cascading parse errors on the user's own line with nothing to suggest the cause. **This makes a previously tolerated input an error**: TYPE_MEM with a trailing registry no longer compiles. There are no call sites. Route all five through a new detail::va_args_no_registry, whose variadic specialization is a static_assert naming the reason. Its return_type lives in a base class: a failed static_assert marks the record invalid on clang, so a member declared alongside it is not found and the cascade returns. With the base, gcc reports exactly one error and clang leads with the message. A return type containing a top-level comma still arrives as several macro arguments and reassembles inside the template argument list, which is what tells the two cases apart - the same discrimination va_args already relies on, and the reason DEFINE_OVERRIDER_MEM can stop using mp_back for it. DETAIL_OVERRIDE_MEM forwards the return type to a new _AUX helper, which is variadic rather than taking a named RET: a comma-bearing return type would otherwise be split into several arguments before _AUX could receive it, and the expansion would fail on arity. Tests: a comma-bearing return type through all three _MEM overrider shapes plus TYPE_MEM and OVERRIDER_MEM, which nothing covered before and which va_args_no_registry is now solely responsible for; and a compile-fail test for the rejected registry. 204/204. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E53cDWKgiva4cfH48EtvMP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Alternative design for #53, exploring a different API shape than #120
(
feature/member-overriders). Independent branches - neither depends on theother, and this is deliberately a separate PR to compare approaches, not a
replacement.
Six new macros mirroring
BOOST_OPENMETHODand its overrider macros, butdeclaring static member functions instead of free ones. No implicit
this, no receiver binding - dispatch is still entirely by the method's ownvirtual parameters, exactly as for a free method.
BOOST_OPENMETHOD_MEMdeclares a method as a static member function,overloadable exactly like a free method (its tag is generated per
expansion, not
ID-derived, which is what makes the overload possible).BOOST_OPENMETHOD_TYPE_MEMnames a member method's coremethod<>type,since
BOOST_OPENMETHOD_TYPEcan't.BOOST_OPENMETHOD_OVERRIDE_MEM/_DECLARE_OVERRIDER_MEM/_DEFINE_OVERRIDER_MEMadd an overrider, as a static member function, toeither a free method or a member method (
Class::method). Being a membergives it the same access to its class's private state as any other member,
with no
frienddeclaration.BOOST_OPENMETHOD_OVERRIDER_MEMfinds a member overrider's key (fn,method_type) from outside, for explicit calls and fornext/has_nextvia the core API.
No
core.hppchanges: each overrider registers through a per-overrider"key" struct holding a
BOOST_FORCEINLINEtrampoline, sooverride_aux/thunk/validate_overrider_parameterall see an ordinaryfunction pointer, unchanged.
Known limitation: a
_MEMoverrider's body and key-accessor are eachnamed once, overloaded purely on
(return type, parameters)- never onwhich method they override, since a qualified
IDcan't be pasted into anew declaration. At most one overrider of a given exact signature per class,
regardless of method. Pinned by
test/compile_fail_member_overrider_signature_collision.cpp.doc/modules/ROOT/pages/friends.adocis retitled "Members and Friends" inthe nav and gains a
_MEMtutorial before the existingfriendcontent,which it supersedes for classes under the caller's control.
Test plan
ctest- 203/203 passing (197 baseline +test_member_method.cpp(2cases) + 3 new compile-fail tests)
design leans on nested-class complete-class-context bodies and
function-template address deduction, both flagged as MSVC risk during
design)
doc/build_antora.sh- full site build, no new warnings; verified nostray backticks and no MrDocs artifact leakage in the touched/new
pages and six new reference pages
rolex/8example andmember.cppsnippet run manually, outputmatches expected ($5000 / $10000 / $985000, bark/hiss)
🤖 Generated with Claude Code