Я добавлю к ответу Джесси о, казалось бы, своеобразном поведении GCC при компиляции:
typedef A<T> A;
vs
typedef ::A<T> A;
Это также относится к использованию операторов в форме:
using A = A<T>;
using A = ::A<T>;
Кажется, что в GCC происходит то, что во время компиляции оператора typedef/using, объявляющего B::A, символ B::A становится допустимым кандидатом внутри самого оператора using. т.е. при произнесении using A = A<T>;
или typedef A<T> A;
GCC считает как ::A
, так и B::A
допустимыми кандидатами на A<T>
.
Это кажется странным поведением, потому что, как следует из вашего вопроса, вы не ожидаете, что новый псевдоним A станет допустимым кандидатом в самом typedef, но, как также говорит ответ Джесси, все, что объявлено в классе, становится видимым для всего остального внутри класса - и в этом случае, по-видимому, даже сама декларация. Этот тип поведения может быть реализован таким образом, чтобы разрешить определение рекурсивного типа.
Решение, которое вы нашли, состоит в том, чтобы указать для GCC, какой именно A вы имеете в виду в typedef, и тогда он больше не жалуется.
person
pyrachi
schedule
30.01.2014
A
используется до объявления локальногоA
, возникает эта ошибка. При этом любое использованиеA
(объявление члена) доtypedef ::A<T> A
; выдаст ту же ошибку. Перемещение объявления ниже изменитA
на локальное, а также исправит ошибку. То же самое и сtypedef A<T> A
, вы используете глобальноеA
раньше, слева, а затем сразу же повторно объявляете его справа. Это просто g++, гарантирующий, что все вхожденияA
в классе будут иметь одно и то же значение (не::A
, это не меняется). - person the swine   schedule 29.03.2016