Почему не допускается прямое объявление класса, который будет typedef?

Если я хочу использовать указатель на класс и не выполняю с ним никаких операций, мы можем пересылать объявление класса. Но если это 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();
}

person balki    schedule 22.06.2011    source источник


Ответы (1)


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

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

РЕДАКТИРОВАТЬ: расширение вашего конкретного примера:

После объявления шаблона 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
person David Rodríguez - dribeas    schedule 22.06.2011
comment
Да, я понимаю это, но почему это так? Однако в конечном итоге он укажет на тип. Не нарушает ли это использование форвардного объявления? - person balki; 22.06.2011
comment
@balki: да: / Например, большинство людей будут #include <string> вместо того, чтобы идти долгой дорогой и вперед, объявляют std::basic_string. - person Matthieu M.; 22.06.2011
comment
@balki: Я добавил ссылку на ответ на другой вопрос, где объясняется семантика typedef. Исходный вопрос - C, но он применим и здесь, и ответ содержит некоторое содержание C ++. По сути, объявление определяемого пользователем типа добавляет тип (и, возможно, идентификатор, который на него ссылается) в определенное пользователем пространство идентификаторов, в то время как typedef создает идентификатор в другом пространстве идентификаторов, который ссылается на данный тип. - person David Rodríguez - dribeas; 22.06.2011
comment
@Matthieu: вы не можете пересылать объявление std :: basic_string. - person ; 22.06.2011
comment
@Fanael: ты можешь template<typename, typename, typename> class basic_string; физически, был вопрос, можно тебе это или нет? - person Matthieu M.; 22.06.2011
comment
@Fanael: в gcc см. Заголовок bits/stringfwd.h. - person Matthieu M.; 22.06.2011
comment
Если бы вы сделали это в пространстве имен std, это было бы неопределенное поведение. Разработчикам стандартных библиотек это разрешено, а вам - нет. - person ; 22.06.2011