Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't clang allow accessing a nested enum class through an instance?

Consider the following code:

struct S {
    enum class EnumClass {
        one
    } ;

    enum Enum {
        one
    };
};

int main()
{
    S s;
    S::EnumClass e = s.EnumClass::one; // <- Doesn't compile with clang
    S::Enum e11 = s.Enum::one;
    S::Enum e12 = s.one;
}

Everything works with GCC, but clang (neither 3.8 nor 3.9) does not compile s.EnumClass::one, giving an error: 'S::EnumClass::one' is not a member of class 'S'.

Given the fact that unscoped enums work fine, it seems like a bug.

like image 398
danpla Avatar asked Apr 25 '18 17:04

danpla


Video Answer


1 Answers

This is a bug in gcc1. The relevant wording is in [expr.ref]p2:

In either case, the id-expression [here: EnumClass::one] shall name a member of the class or of one of its base classes.

EnumClass::one does not refer to a member of a class, it's a member of an enum. It doesn't matter whether that enum is part of the class, it's just that the member one itself is not part of the class.

But is Enum::one part of the class? Yes, according to [class.member]p1:

Members of a class are data members, member functions, nested types, enumerators, and member templates and specializations thereof.

and made more explicit in [class.member]p3:

The enumerators of an unscoped enumeration defined in the class are members of the class.


1: I would even go as far as to call it a bug in the standard, as there doesn't seem to be any (technical) reason why this should be disallowed and I think it would be a good idea to allow it. There are talks about allowing it though, so let's see what the committee decides.

like image 172
Rakete1111 Avatar answered Sep 21 '22 18:09

Rakete1111