Title
Ambiguous lookup for type aliases in reflection
Status
review
Section
7.6.2.10 [expr.reflect]
Submitter
Richard Smith

Created on 2026-05-06.00:00:00 last changed 1 week ago

Messages

Date: 2026-05-20.07:01:56

CWG 2026-05-19

Seeking EWG's approval via paper issue #2795.

Date: 2026-05-20.07:01:56

Proposed resolution (approved by CWG 2026-05-19):

Change in 7.6.2.10 [expr.reflect] paragraph 5 as follows:

  • ...
  • Otherwise, if lookup finds a namespace alias (9.9.3 [namespace.alias]), all declarations found by name lookup shall have the same target scope, and R represents that such a namespace alias.
  • ...
  • Otherwise, if lookup finds a type alias A,:
    • If any declaration found by name lookup introduced a template parameter T, R represents the underlying entity of T. A if A was introduced by the declaration of a template parameter; otherwise,
    • Otherwise, all declarations found by name lookup shall have the same target scope, and R represents A such a type alias.
    [ Example:
      namespace A {
        using T = int;
      }
      namespace B {
        using T = int;
      }
      using namespace A;
      using namespace B;
      auto r = ^^T;       // error: lookup finds type aliases with different target scopes
    
    -- end example ]
  • ...
Date: 2026-05-20.07:01:56

Possible resolution (option 2) [SUPERSEDED]:

Change in 7.6.2.10 [expr.reflect] paragraph 5 as follows:

  • ...
  • Otherwise, if lookup finds a namespace alias (9.9.3 [namespace.alias]), R represents that an unspecified namespace alias among the lookup results.
  • ...
  • Otherwise, if lookup finds a type alias A, R represents the underlying entity of A if A was introduced by the declaration of a template parameter; otherwise, R represents A an unspecified type alias among the lookup results.
    [ Example:
      namespace A {
        using T = int;
      }
      namespace B {
        using T = int;
      }
      using namespace A;
      using namespace B;
      auto r = ^^T;       // OK, represents either A::T or B::T
    
    -- end example ]
  • ...
Date: 2026-05-06.00:00:00

Consider:

  namespace A {
    using T = int;
  }
  namespace B {
    using T = int;
  }
  using namespace A;
  using namespace B;
  T t;                // #1, OK
  auto r = ^^T;       // #2, ???

While 6.1 [basic.pre] paragraph 8 clarifies that #1 is well-formed by considering the underlying type, the treatment of #2 is unclear.

History
Date User Action Args
2026-05-20 07:01:56adminsetmessages: + msg8584
2026-05-20 07:01:56adminsetstatus: open -> review
2026-05-09 06:52:43adminsetmessages: + msg8574
2026-05-09 06:52:43adminsetmessages: + msg8573
2026-05-06 00:00:00admincreate