Skip to content

Using-declarations depending on a template parameter (using TemplateParam::member;) are silently dropped #1258

Description

@correaa

TLDR: boost::multi::array has a member function called .size(). This member is defined and is inherited from a base class boost::multi::detail::array_types that is private and re-exported in the inheritance chain with using boost::multi::detail::array_types::size. .size() doesn't appear in the documentation of boost::multi::array.

https://correaa.github.io/boost-multi/multi/reference/boost/multi/array-0ad.html

https://correaa.gitlab.io/boost-multi/multi/reference/boost/multi/array-0ad.html

A possible workaround, is to define a forward member function in the leaf class: auto size() const { return boost::multi::detail::array_types::size(); }, but it is too verbose and I would have to do it with tens of other similar functions.

Summary

A using-declaration that re-exports a member from a template-parameter base (e.g. re-exposing a privately-inherited member so it's public) is not extracted at all — it doesn't appear on the declaring class's own page, and produces no warning/diagnostic. The same using-declaration from a concrete, non-dependent base is extracted and documented (just not inherited further down — possibly a separate issue).

Minimal reproduction

repro.hpp:

namespace ns {

struct Base {
    using size_type = int;
    constexpr auto size() const noexcept -> size_type { return 42; }
};

template<class T, class BaseT = Base>
struct Mid : private BaseT {
    using typename BaseT::size_type;  // dependent using-declaration
    using BaseT::size;                // dependent using-declaration

    /// A member declared directly (not via using), for comparison.
    constexpr auto count() const noexcept -> int { return 1; }
};

}  // namespace ns

mrdocs.yml:

source-root: include/
compilation-database: build/compile_commands.json
input:
  - include/repro.hpp
output: out
generator: adoc
multipage: true
extract-all: true
include-symbols:
  - "ns"

Built via a normal CMake-generated compile_commands.json (cmake -B build -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON), then mrdocs mrdocs.yml.

Actual output (out/ns/Mid.adoc)

Only count shows up. No "Using Declarations" section at all:

== Member Functions

[cols="1,4"]
|===
| Name| Description
| xref:ns/Mid/count.adoc[`count`]
| A member declared directly (not via using), for comparison.
|===

Expected output

size and size_type should also be documented on Mid, the same way they are when BaseT is a fixed, non-template type instead of a template parameter (in that case they do get extracted, under a "Using Declarations" section — just still not inherited by classes further derived from Mid).

Why this matters

This is exactly the shape of a common idiom: a class template privately inherits another type that is itself one of its template parameters (a customizable implementation detail), then re-exports selected members with using Param::member; to keep a narrow public interface. In Boost.Multi, array_types<T, D, ElementPtr, Layout> does this for size, num_elements, offset, extent, and others — all silently absent from the generated reference for array/subarray, with no diagnostic pointing at why.

Environment

MrDocs version 0.8.0+baf81eb80f21
Built with LLVM 22.0.0git

clang++ 21.1.8, cmake 4.2.3, Linux x86_64.

Metadata

Metadata

Assignees

No one assigned

    Labels

    fixSomething that is broken / incorrect behavior

    Type

    No type

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions