Title
Can we omit the template disambiguator in nested-name-specifiers in type-only contexts?
Status
drafting
Section
13.3 [temp.names]
Submitter
Richard Smith

Created on 2024-06-13.00:00:00 last changed 2 weeks ago

Messages

Date: 2024-06-14.20:31:51

Proposed resolution (approved by CWG 2024-06-14):

Change in 13.3 [temp.names] paragraph 3 as follows:

A name is in a transitive type-only context if
  • it is in a type-only context (13.8.1 [temp.res.general]) and is not the terminal name of a nested-name-specifier, or
  • it is the terminal name of a nested-name-specifier that precedes a name in a transitive type-only context (possibly with an intervening template keyword).
A < is interpreted as the delimiter of a template-argument-list if it follows a name that is not a conversion-function-id and
  • that follows the keyword template or a ~ after a nested-name-specifier or in a class member access expression, or
  • for which name lookup finds the injected-class-name of a class template or finds any declaration of a template, or
  • that is an unqualified name for which name lookup either finds one or more functions or finds nothing, or
  • that is a terminal name in a using-declarator (9.9 [namespace.udecl]), in a declarator-id (9.3.4 [dcl.meaning]), or in a transitive type-only context other than a nested-name-specifier (13.8 [temp.res]).
Date: 2024-06-13.00:00:00

Are the following examples well-formed? Note the absence of a template disambiguator:

  template<typename T> class C {
   T::X<int> g1();      // #1
   T::X<int>::Y g2();   // #2
  };

  template<typename T>
  T::X<int> h1();       // #3
  template<typename T>
  T::X<int>::Y h2();    // #4

The return type is a type-only context per 13.8.1 [temp.res.general] paragraph 4. However, 13.3 [temp.names] paragraph 3 excludes nested-name-specifiers from the set of situations where template can be omitted. That means that #1 and #3 are valid; X is not part of a nested-name-specifier. However, #2 and #4 are invalid; the template disambiguator is missing. Those examples ought to be valid, too.

History
Date User Action Args
2024-12-06 09:40:31adminsetstatus: ready -> drafting
2024-11-19 11:51:56adminsetstatus: tentatively ready -> ready
2024-06-14 20:31:51adminsetstatus: open -> tentatively ready
2024-06-14 16:15:24adminsetmessages: + msg7734
2024-06-13 00:00:00admincreate