范围解析运算符

时间:2012-04-07 01:10:16

标签: c++ scope g++

我偶然碰巧在我看到的一个源代码中找到了这个。所以,我在这里给出了一个类似的小例子。

在文件 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 个答案:

答案 0 :(得分:41)

此代码无效。

g ++中的错误是它接受了代码。请参阅"g++ does not treat injected class name correctly."该错误已于2009年解决,因此应在任何最新版本的g ++中修复。

答案 1 :(得分:16)

澄清情况,如§9/ 2中所述:

  

在看到类名后立即将类名插入到作用域中。类名也插入到类本身的范围内;这被称为注入类名。出于访问检查的目的,inject-class-name被视为公共成员名称。

但是,如§3.4.3.1/ 1中所述:

  

如果qualified-id的nested-name-specifier指定了一个类,则在类(10.2)的范围内查找在嵌套的namespecifier之后指定的名称,但下面列出的情况除外。

     

[......§3.4.3.1/ 2]:

     

在查找中,构造函数是可接受的查找结果,而嵌套名称说明符指定类C:

     

- 如果在C中查找的nested-name-specifier之后指定的名称是C的注入类名(第9条)[...],则该名称被认为是命名构造函数的名称。 C级。

     

[...例如:]

struct A { A(); };
[ ... ]
A::A a; // error, A::A is not a type name
struct A::A a2; // object of type A