为什么代码“foo :: foo :: foo :: foob”编译?

问题描述:

一位同事不小心写了这样的代码:为什么代码“foo :: foo :: foo :: foob”编译?

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编译此。

这个编译的规则是什么?

+14

你能成为一个更具体一点关于哪一部分,你不要指望,以顺利地编译? – neuhaus

+1

它没有:https://godbolt.org/g/j2AbVn – Timbo

+1

有一个缺少包含文件和for循环缺少一个语句,但除了它编译 – Johan

injected-class-name在这里使用,

其自己的定义作为本身为lookup目的的公共成员类型别名内的类的名称(用于命名一个constructor时除外):这个被称为注射类名

然后

foo:: 
foo:: 
foo::foob 

foo::foo::foo::foobfoo::foob相同。

然后for (auto x : {foo::foobar, foo::fbar, foo::foob })range-based for loop (since C++11),它在由3个枚举器形成的braced-init-list上迭代。

我改变了这种代码,以这样的:

#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; 
} 

的循环运行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 }