Operador de resolução de escopo

Eu acidentalmente aconteceu para encontrar isso em um dos códigos-fonte que eu estava olhando. Então, estou dando um exemplo menor semelhante aqui.

No arquivo test.h :

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

No arquivo test.cpp :

 #include "test.h" int main() { test test1; test::test test2; test::test::test test3; return 0; } 

Primeiro de tudo, há uma razão para declarar test2 dessa maneira? Em segundo lugar, este código compila muito bem em g ++ versão 4.4.3 e versões inferiores. Existe algo no padrão C ++, dizendo que os operadores de resolução de escopo são ignorados quando não há necessidade de resolver o escopo?

Este código não é válido.

Foi um bug no g ++ que aceitou o código. Veja “g ++ não trata corretamente o nome da class injetada”. O bug foi resolvido como corrigido em 2009, portanto, ele deve ser corrigido em qualquer versão recente do g ++.

Para esclarecer a situação, conforme especificado no § 9/2:

Um nome de class é inserido no escopo no qual ele é declarado imediatamente após o nome da class ser visto. O nome da class também é inserido no escopo da própria class; isso é conhecido como o nome da class injetada. Para fins de verificação de access, o nome da class injetada é tratado como se fosse um nome de membro público.

No entanto, conforme especificado em §3.4.3.1 / 1:

Se o nested-nome-especificador de um ID-qualificado nomear uma class, o nome especificado após o identificador de nomes nesteds é procurado no escopo da class (10.2), exceto para os casos listados abaixo.

[… §3.4.3.1 / 2]:

Em uma pesquisa em que o construtor é um resultado de pesquisa aceitável e o nested nome-especificador indica uma class C:

– se o nome especificado após o nested-nome-especificador, quando pesquisado em C, for o nome da class injetada de C ([…] Cláusula 9), o nome será considerado para nomear o construtor da class C.

[… exemplo:]

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