Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is forward declaration of a class which will be a typedef not allowed?

If I want to use a pointer to a class and I dont do any operations on it, we can forward declare the class. But if that happens to be a typedef, why is it not allowed? In the following example, it compiles only i include the commented code but why does compiler wants to know about it at that point? How do I forward declare something which may be a typedef. Is there any changes in this behavior in 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();
}
like image 773
balki Avatar asked Jun 22 '11 10:06

balki


1 Answers

A typedef does not create a type it just adds a new name to an existing type, and you cannot forward declare it. I recommend that you read this answer to a different related question, I think it can help in understanding the differences between a typedef and a declaration of a user defined type.

You can, on the other hand, forward declare the actual type, and then add the typedef in place.

EDIT: Extending on your particular example:

After declaring the temp template, the identifier temp is available in the user defined types identifier space (which is different to the rest of the symbols' identifier space). The typedef will create an alias in the global identifier space by the name of later, so after the commented lines (were they uncommented), the user defined types identifier space will contain temp referring to the template, and the identifier later residing in the global identifier space will refer to the concrete instantiation temp<int>. (What a mouthful of "identifier" and "space"!)

On the other hand, if you forward declare the class as in the first uncommented line class later;, what you are doing is adding an identifier to the user defined types identifier space. The difference can be seen in the following example:

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
like image 68
David Rodríguez - dribeas Avatar answered Oct 23 '22 10:10

David Rodríguez - dribeas