virtual_ptr: allow a virtual_ptr to the class as a member of the class - #109
Merged
Merged
Conversation
struct Node {
virtual ~Node() = default;
virtual_ptr<Node> next;
};
failed to compile with gcc 16: `invalid use of incomplete type 'struct
Node'`, from `std::is_polymorphic_v<Node>`. Three member templates of
`virtual_ptr` - the constructor from `Other*`, and the assignments from
`Other&` and `Other*` - constrained themselves with
`IsPolymorphic<Class, Registry> && std::is_constructible_v<Class*, Other*>`
in a default template argument. The first operand does not depend on `Other`,
so gcc evaluates it when the class itself is instantiated - for the member
declaration, where `Node` is still incomplete. libstdc++ 13 answered
`is_polymorphic` on an incomplete type; 16 rejects it, as the standard allows.
The check now names `Other`, through an ignored trailing pack on the
exposition-only `IsPolymorphic`, which makes it dependent and defers it to the
first use of the member - where the class is complete. And it sits in a
defaulted parameter of its own, after the pointer-convertibility test: clang
reaches these candidates during overload resolution for the member's implicit
copy assignment, with `Other` = `const virtual_ptr<Node>`, and substitution
stops at the first condition that fails. That is the shape CLAUDE.md
prescribes for MrDocs anyway, and the rendered constraint reads the same.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDgWtJsC4KihJHq73cuCcV
|
An automated preview of the documentation is available at https://109.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-13 17:27:11 UTC |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #109 +/- ##
===========================================
- Coverage 93.62% 93.51% -0.12%
===========================================
Files 22 22
Lines 1694 1695 +1
Branches 505 504 -1
===========================================
- Hits 1586 1585 -1
- Misses 64 66 +2
Partials 44 44
... and 1 file with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
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.
failed to compile with gcc 16:
invalid use of incomplete type 'struct Node', fromstd::is_polymorphic_v<Node>.Three member templates of
virtual_ptr— the constructor fromOther*, and the assignments fromOther&andOther*— constrained themselves withIsPolymorphic<Class, Registry> && std::is_constructible_v<Class*, Other*>in a default templateargument. The first operand does not depend on
Other, so gcc evaluates it when the class itselfis instantiated — for the member declaration, where
Nodeis still incomplete. libstdc++ 13answered
is_polymorphicon an incomplete type; 16 rejects it, as the standard allows.The check now names
Other, through an ignored trailing pack on the exposition-onlyIsPolymorphic, which makes it dependent and defers it to the first use of the member — where theclass is complete. And it sits in a defaulted parameter of its own, after the pointer-convertibility
test: clang reaches these candidates during overload resolution for the member's implicit copy
assignment, with
Other=const virtual_ptr<Node>, and substitution stops at the first conditionthat fails. That is the shape CLAUDE.md prescribes for MrDocs anyway, and the rendered constraint
reads the same.
test/test_virtual_ptr_self_referential.cppcovers the case. Full suite: 165/165 pass locally.🤖 Generated with Claude Code
https://claude.ai/code/session_01JQa4fuiwcfsheZYTCyfPPr