Почему прямое объявление класса, который будет typedef, не допускается? - PullRequest
8 голосов
/ 22 июня 2011

Если я хочу использовать указатель на класс, и я не выполняю над ним никаких операций, мы можем объявить класс вперед. Но если это происходит с typedef, почему это не разрешено? В следующем примере он компилируется только с включенным закомментированным кодом, но почему компилятор хочет знать об этом в этот момент? Как мне переслать объявить что-то, что может быть typedef. Есть ли какие-либо изменения в этом поведении в c ++ 0x?

#include <iostream>
using namespace std;
/*
template<class T>
class temp;

typedef temp<int> later;
*/
class later;
void somefunc(later*);
int main()
{
  later* l;
  somefunc(l);
  return 0;
}
//The following is in someother file/compilation unit.
template<class T>
struct temp
{
  public:
    void print()
    {
        T t(5);
        std::cout<< "helloworld: " << t << std::endl;
    }
};
typedef temp<int> later;
void somefunc(later* l)
{
  l = new later();
  l->print();
}

1 Ответ

6 голосов
/ 22 июня 2011

typedef не создает тип, он просто добавляет новое имя к существующему типу, и вы не можете его объявить вперёд.Я рекомендую вам прочитать этот ответ на другой связанный вопрос, я думаю, что он может помочь в понимании различий между typedef и объявлением пользовательского типа.

Вы можете, нас другой стороны, форвард объявляет фактический тип, а затем добавляет typedef на место.

EDIT: расширение в вашем конкретном примере:

После объявления шаблона temp идентификатор temp доступно в пространстве идентификаторов определенных пользователем типов (которое отличается от остального пространства идентификаторов символов).Typedef создаст псевдоним в глобальном пространстве идентификаторов с именем later, поэтому после закомментированных строк (если они не были прокомментированы) пространство идентификаторов пользовательских типов будет содержать temp со ссылкой на шаблон и идентификатор later находящийся в глобальном пространстве идентификаторов будет ссылаться на конкретный экземпляр temp<int>.(Что за глоток «идентификатора» и «пробела»!)

С другой стороны, если вы перенаправляете объявление класса, как в первой строке без комментария class later;, вы добавляете идентификатор кпространство идентификаторов определенных пользователем типов.Разницу можно увидеть в следующем примере:

class A;           // Creates A identifier only in user defined types space
typedef int B;     // Creates B identifier in the global identifier space

void A(){}         // Ok: A will refer to void A(); class A will refer to the type
//void B(){}       // Error: B symbol collides with the typedef
...