Skip to content

CWG3026 [expr.unary.op] Wording is ambiguous: Pointer to member of which class? #705

Open
@hubert-reinterpretcast

Description

@hubert-reinterpretcast

Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong

Reference (section label): expr.unary.op

Link to reflector thread (if any): N/A

Issue description:
There should be little controversy that the following should compile, but the wording is unclear: https://godbolt.org/z/aYo86aEer

struct A {
  union { int x; };
  int y;
};
struct B : A {};

template <typename> struct Q;
template <> struct Q<A> {};
template <typename T> Q<T> f(int T::*);

Q<A> g() { return f(&B::x); }
Q<A> h() { return f(&B::y); }

https://wg21.link/expr.unary.op under bullet 3.1 has:

If the operand is a qualified-id naming a non-static or variant member m of some class C, other than an explicit object member function, the result has type “pointer to member of class C of type T” and designates C​::​m.

In the above:

  • x is a variant member both of the anonymous union and of A, and
  • y is a non-static member of both A and of B.

It seems C in the wording is not quite unique.

Suggested resolution:

If the operand is a qualified-id naming a non-static or variant class member m of some class C, other than an explicit object member function, then let C be

  • the class of which m is a direct member if m is not a variant member, and otherwise
  • the class, that is not an anonymous union, of which m is a variant member.

The the result has type “pointer to member of class C of type T” and designates C​::​m. [Note: A qualified-id that names a member of a namespace-scope anonymous union is considered to be a class member access expression ([expr.prim.id.general]) and cannot be used to form a pointer to member.]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions