Search code examples
c++c++11gcclanguage-lawyernames

Why is the code "foo::foo::foo::foob" compiling?


A co-worker accidentally wrote code like this:

struct foo {
  foo() : baz(foobar) {}
  enum bar {foobar, fbar, foob};
  bar baz;
};

void f() {
  for( auto x : { foo::foobar,
                  foo::fbar,
                  foo::
                  foo::
                  foo::foob } );
    // ...
}

GCC 5.1.0 compiles this.

What's the rule that makes this compile?


Solution

  • The injected-class-name is used here,

    the name of the class within its own definition acts as a public member type alias of itself for the purpose of lookup (except when used to name a constructor): this is known as injected-class-name

    then

    foo::
    foo::
    foo::foob
    

    i.e. foo::foo::foo::foob is same as foo::foob.

    And then for (auto x : {foo::foobar, foo::fbar, foo::foob }) is a range-based for loop (since C++11), which iterates on the braced-init-list formed by the 3 enumerators.