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++ 标准中是否有一些东西,说,当不需要解析范围时,范围解析运算符会被忽略?

4

2 回答 2

42

此代码无效。

这是 g++ 中的一个错误,它接受了代码。请参阅“g++ 未正确处理注入的类名”。 该错误已在 2009 年修复,因此它应该在任何最新版本的 g++ 中修复。

于 2012-04-07T01:19:47.070 回答
16

To clarify the situation, as specified in §9/2:

A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name.

However, as specified in §3.4.3.1/1:

If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-namespecifier is looked up in the scope of the class (10.2), except for the cases listed below.

[ ... §3.4.3.1/2]:

In a lookup in which the constructor is an acceptable lookup result and the nested-name-specifier nominates a class C:

— if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C (Clause 9) [ ... ] the name is instead considered to name the constructor of class C.

[ ... example: ]

struct A { A(); };
[ ... ]
A::A a; // error, A::A is not a type name
struct A::A a2; // object of type A
于 2012-04-07T01:29:22.007 回答