Skip to content

virtual_ptr: allow a virtual_ptr to the class as a member of the class - #109

Merged
jll63 merged 1 commit into
boostorg:developfrom
jll63:fix/virtual-ptr-incomplete-class
Sep 13, 2026
Merged

virtual_ptr: allow a virtual_ptr to the class as a member of the class#109
jll63 merged 1 commit into
boostorg:developfrom
jll63:fix/virtual-ptr-incomplete-class

Conversation

@jll63

@jll63 jll63 commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator
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.

test/test_virtual_ptr_self_referential.cpp covers the case. Full suite: 165/165 pass locally.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JQa4fuiwcfsheZYTCyfPPr

    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
@cppalliance-bot

Copy link
Copy Markdown

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

codecov Bot commented Sep 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.51%. Comparing base (35f4e39) to head (d44aa59).
⚠️ Report is 11 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             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              
Files with missing lines Coverage Δ
include/boost/openmethod/core.hpp 93.09% <ø> (ø)

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eb2d5d8...d44aa59. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jll63
jll63 merged commit 10bdfe5 into boostorg:develop Sep 13, 2026
55 of 56 checks passed
@jll63
jll63 deleted the fix/virtual-ptr-incomplete-class branch September 13, 2026 19:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants