This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2026-03-08


3160. Grammar ambiguity with class member declarations

Section: 11.4  [class.mem]     Status: open     Submitter: Tam S. B.     Date: 2025-08-08

(From submission #741.)

Consider:

  typedef int t1, t2, t3, t4;

  struct A {
    static A(*t1)(); // #1, function pointer
    static A(t2)();  // #2, invalid constructor declaration
    static A(t3);    // #3, invalid constructor declaration
    A(t4);           // #4, constructor
  };

A disambiguation rule is missing that would cause the indicated (desired) outcomes.

Suggested resolution:

Add a new subclause at the end of 11.4 [class.mem]:

Ambiguity resolution [class.mem.ambig]

An ambiguity can arise in a member-declaration when a type-name is enclosed in parentheses. In this case, the choice is between the declaration of a function with an unnamed parameter and the declaration of a member with redundant parentheses around the declarator-id. The resolution is to consider the type-name as a simple-type-specifier rather than a declarator-id. As in 8.11 [stmt.ambig], the disambiguation is purely syntactic and can result in an ill-formed interpretation.

  typedef int t1, t2, t3;
  template<class> struct u1;
  struct A {
    A(t1);            // OK, declares constructor having unnamed parameter of type int
    typedef A(t2);    // error: constructor declaration with typedef
    friend A(t3)();   // error: declares function named A that returns a function with no return type
    A(u1);            // error: placeholder for deduced class type cannot appear in this context (9.2.9.8 [dcl.type.class.deduct])
  };