Why is the code “foo::foo::foo::foob” compiling? [duplicate]

谁都会走 提交于 2020-02-01 00:42:16

问题


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?


回答1:


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.




回答2:


I changed this code to this:

#include <initializer_list>
#include <iostream>
struct foo {
  foo() : baz(foobar) {}
  enum bar {foobar, fbar, foob};
  bar baz;
};

int main() {
  for( auto x : { foo::foobar,
                  foo::fbar,
                  foo::
                  foo::
                  foo::foob } )
                  {
                      std::cout << "x=" << x << std::endl;
                  }
  return 0;
}

for loop runs 3 times. output is: "x=1 x=2 x=3".


foo::foo::foo::foob is the same foo::foob. So

for( auto x : { foo::foobar,
                  foo::fbar,
                  foo::
                  foo::
                  foo::foob } )

is the same

for( auto x : { foo::foobar, foo::fbar, foo::foob } )
{
}

It means that x is in range { foo::foobar, foo::fbar, foo::foob }



来源:https://stackoverflow.com/questions/46805449/why-is-the-code-foofoofoofoob-compiling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!