为什么要编译代码“foo::foo::foo::foob”?[复制]

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

提问人:sbi 提问时间:10/18/2017 最后编辑:songyuanyaosbi 更新时间:10/30/2017 访问量:2106

问:

一位同事不小心写了这样的代码:

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 对此进行了编译。

编译的规则是什么?

C++ C++11 GCC 语言律师 名称

评论

15赞 neuhaus 10/18/2017
您能否更具体地说明您不希望干净地编译哪个部分?
1赞 Timbo 10/18/2017
它没有:godbolt.org/g/j2AbVn
1赞 Johan 10/18/2017
缺少一个包含文件,并且 for 循环缺少一个语句,但除此之外,它会编译
1赞 user7860670 10/18/2017
这可以简化为struct foo { static const int v{42}; }; auto x{foo::foo::foo::foo::foo::v};
2赞 songyuanyao 10/18/2017
@sbi 哪个部分让你感到困惑?注入的类名?基于范围的 for 循环?

答:

31赞 songyuanyao 10/18/2017 #1

这里使用了 injected-class-name

类在其自身定义中的名称充当其自身的公共成员类型别名,用于查找(用于命名构造函数时除外):这称为 injected-class-name

然后

foo::
foo::
foo::foob

即 与 相同。foo::foo::foo::foobfoo::foob

然后是一个基于范围的 for 循环(从 C++11 开始),它迭代由 3 个枚举器形成的支撑初始化列表for (auto x : {foo::foobar, foo::fbar, foo::foob })

4赞 Gor Asatryan 10/18/2017 #2

我把这段代码改成了:

#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 循环运行 3 次。输出为:“x=1 x=2 x=3”。


foo::foo::foo::foob是一样的. 所以foo::foob

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

是一样的

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

这意味着在范围内x{ foo::foobar, foo::fbar, foo::foob }