Ответ 1
Этот код недействителен.
Это была ошибка в g++, которая приняла код. См. "g++ неправильно обрабатывает введенное имя класса" . Ошибка была решена как исправленная в 2009 году, поэтому она должна быть исправлена в любой новой версии 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 и более низких версиях. Есть ли что-то в стандарте С++, говоря, что операторы разрешения области действия игнорируются, когда нет необходимости в разрешении области?
Этот код недействителен.
Это была ошибка в g++, которая приняла код. См. "g++ неправильно обрабатывает введенное имя класса" . Ошибка была решена как исправленная в 2009 году, поэтому она должна быть исправлена в любой новой версии g++.
Чтобы прояснить ситуацию, как указано в § 9/2:
Имя класса вставляется в область, в которой объявляется сразу после просмотра имени класса. Имя класса также вставляется в область самого класса; это известно как имя введенного класса. Для проверки доступа имя введенного класса рассматривается как имя публичного участника.
Однако, как указано в п. 3.4.3.1/1:
Если спецификатор вложенного имени квалифицированного идентификатора назначает класс, имя, указанное после вложенного имени, проверяется в классе класса (10.2), за исключением случаев, перечисленных ниже.
[... §3.4.3.1/2]:
В поиске, в котором конструктор является приемлемым результатом поиска, а спецификатор вложенных имен назначает класс C:
- если имя, указанное после вложенного имени-спецификатора, при поиске на C, является введенным классом-именем C (раздел 9) [...], вместо этого имя будет называться конструктором класс C.
[... example:]
struct A { A(); };
[ ... ]
A::A a; // error, A::A is not a type name
struct A::A a2; // object of type A