作用域解析运算符

33

我在查看源代码时意外地发现了这个内容。所以,我在此提供一个类似但更简短的例子。

在文件 test.h 中:

#include<iostream>

class test{
    int i;
public:
    test(){}
    //More functions here
};

在文件 test.cpp 中:

#include "test.h"

int main()
{
    test test1;
    test::test test2;
    test::test::test test3;
    return 0;
}

首先,声明test2那样做有什么理由吗?其次,在g++版本4.4.3及更低版本中,此代码可以编译通过。C++标准中是否有规定当没有需要解析作用域时,作用域解析运算符会被忽略?

2个回答

42

该代码无效。

这是g ++中存在的错误,导致其接受了该代码。请参见“g ++没有正确处理注入的类名”。该错误已于2009年被解决并修复,因此任何最新版本的g++应该都已经修复了该问题。


1
奇怪的事情:Ideone编译了这段代码:http://ideone.com/Duwzy 他们在使用什么GCC? - kralyk
3
是的。注意到ideone使用的是gcc 4.3.4,并且如果你使用它的"C++0x"选项进行编译,这会使用gcc 4.5.1,并拒绝该代码。 - James McNellis
@Ashwin:你的问题说它在4.4.3下编译得非常好。;-] - ildjarn
哦,我是指4.4.3之后的版本 :-) - Ashwin

16
为了清晰情况,在§9/2中指定:类名在其声明的作用域中立即插入。类名还插入到类本身的作用域中;这称为注入类名。为了访问检查,注入类名被视为公共成员名称。然而,在§3.4.3.1/1中指定:如果限定符ID的嵌套名称指定了一个类,那么在嵌套名称限定符之后指定的名称将在该类的作用域内查找(10.2),除了下面列出的情况。在查找构造函数是可接受的查找结果且嵌套名称限定符提名了类C的查找中:如果在C中查找嵌套名称限定符之后指定的名称是C的注入类名(Clause 9)[...],则该名称被视为类C的构造函数。[...例子:]
struct A { A(); };
[ ... ]
A::A a; // error, A::A is not a type name
struct A::A a2; // object of type A

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接