This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4435. meta::has_identifier doesn't handle all types

Section: 21.4.6 [meta.reflection.names] Status: New Submitter: Jakub Jelinek Opened: 2025-10-27 Last modified: 2025-10-29

Priority: 2

View all issues with New status.

Discussion:

The wording for meta::has_identifier doesn't specify what it returns for ^^int or ^^void or ^^Enum.

[2025-10-29; Reflector poll.]

Set priority to 2 after reflector poll.

Move bullet point for aliases before bullet for types. Add "cv-unqualified" to class type and enumeration type. Simplify "!has_template_arguments() is true`" to "has_template_arguments() is false".

Proposed resolution:

This wording is relative to N5014.

  1. Modify 21.4.6 [meta.reflection.names] as indicated:

    consteval bool has_identifier(info r);

    -1- Returns:

    • (1.1) — If r represents an entity that has a typedef name for linkage purposes (9.2.4 [dcl.typedef]), then true.
    • (1.2) — Otherwise, if r represents an unnamed entity, then false.
    • (1.?) — Otherwise, if r represents a type alias, then !has_template_arguments(r).
    • (1.3) — Otherwise, if r represents a type, then true if class type, then !has_template_arguments(r).
      • (1.3.1) — r represents a cv-unqualified class type and has_template_arguments(r) is false, or
      • (1.3.2) — r represents a cv-unqualified enumeration type.
      Otherwise, false.
    • (1.4) — Otherwise, if r represents a function, then true if has_template_arguments(r) is false and the function is not a constructor, destructor, operator function, or conversion function. Otherwise, false.
    • (1.5) — Otherwise, if r represents a template, then true if r does not represent a constructor template, operator function template, or conversion function template. Otherwise, false.
    • (1.6) — Otherwise, if r represents the ith parameter of a function F that is an (implicit or explicit) specialization of a templated function T and the ith parameter of the instantiated declaration of T whose template arguments are those of F would be instantiated from a pack, then false.
    • (1.7) — Otherwise, if r represents the parameter P of a function F, then let S be the set of declarations, ignoring any explicit instantiations, that precede some point in the evaluation context and that declare either F or a templated function of which F is a specialization; true if
      • (1.7.1) — there is a declaration D in S that introduces a name N for either P or the parameter corresponding to P in the templated function that D declares and
      • (1.7.2) — no declaration in S does so using any name other than N.
      Otherwise, false.
    • (1.8) — Otherwise, if r represents a variable, then false if the declaration of that variable was instantiated from a function parameter pack. Otherwise, !has_template_arguments(r).
    • (1.9) — Otherwise, if r represents a structured binding, then false if the declaration of that structured binding was instantiated from a structured binding pack. Otherwise, true.
    • (1.10) — Otherwise, if r represents a type alias, then !has_template_arguments(r).
    • (1.11) — Otherwise, if r represents an enumerator, non-static-data member, namespace, or namespace alias, then true.
    • (1.12) — Otherwise, if r represents a direct base class relationship, then has_identifier(type_of(r)).
    • (1.13) — Otherwise, r represents a data member description (T,N,A,W,NUA) (11.4.1 [class.mem.general]); true if N is not ⊥. Otherwise, false.