Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"using typedef-name ... as class" on a forward declaration

I'm doing some policy-based designs here and I have the need to typedef lots of template types to shorten the names.
Now the problem comes that when I need to use a pointer to one of those types I try to just forward-declare it but the compiler complains with a test.cpp:8: error: using typedef-name ‘Test1’ after ‘class’
It's nothing to do with sizes as I don't need the obj at all, its just a pointer in a ".h" file where I don't want to bring the whole template in.
This is g++:

//Works
class Test{};
class Test;

//Doesn't work
class Test{};
typedef Test Test1;
class Test1;

Any hint?

like image 903
Yogur Avatar asked Feb 14 '10 22:02

Yogur


3 Answers

That's correct. A typedef-name cannot be used in such a forward declaration (this is technically called an elaborated type specifier, and if such a specifier resolves to a typedef-name, the program is ill-formed).

I don't understand why you actually need the forward declaration in the first place. Because if you already have the typedef in place, why not just use that typedef? It's just aswell denoting that class.

Edit: From your comment, it seems you need a designated forward declaration header, much in the same vain of <iosfwd>. So, if you template is called Test_Template_Name_Long, this a header can look like

TestFwd.h

template<typename A, typename B> 
class Test_Template_Name_Long;

typedef Test_Template_Name_Long<int, bool> Test1;

Then you can just use that header, instead of doing class Test1, which the compiler has no clue about what it is (and will think it is a new class, independent of any template and typedef).

like image 168
Johannes Schaub - litb Avatar answered Nov 05 '22 10:11

Johannes Schaub - litb


typedef Test Test1;
class Test1;

fails because the typedef statement serves as the declaration for the Test1 type.

Basically, when the compiler sees the typedef, it remembers that Test1 is a synonym for Test. Then when it sees class Test1;, it thinks there's a new type you are declaring. But it can't treat that as a declaration because the name Test1 is already being used by the typedef.

If you want to use a forward declaration for Test1, for example, you have to put the typedef in each file using that typedef as a forward declaration. Therefore, instead of class Test1;, you'd do:

class Test;
typedef Test Test1;
like image 2
Billy ONeal Avatar answered Nov 05 '22 11:11

Billy ONeal


One more case in which this situation arises is this:

// File: network_fwd.hpp
#ifndef __NETWORK_FWD_HPP__
#define __NETWORK_FWD_HPP__
class Network;
typedef Network GarnetNetwork;
#endif // __NETWORK_FWD_HPP__

// File: network.hpp
#include "network_fwd.hpp"

class GarnetIntLink : public BasicLink
{
  public:

    friend class GarnetNetwork;

};

I had to do that because there was actually a class called GarnetNetwork that I merged into class Network, and I wanted to propagate that throughout the rest of the code using that typedef. GCC still gives this message: error: using typedef-name ‘GarnetNetwork’ after ‘class’.

I really appreciate your help about this case.

NB: By the way I posted this question here because I thought it is pretty much the same thing and in order not to distract the community.

like image 2
Ahmed Nassar Avatar answered Nov 05 '22 12:11

Ahmed Nassar