Neil Kirk
Neil Kirk

Reputation: 21803

How can I make these typedefs work?

These lines are in different header files and end up getting included in a source file in the following order:

class Alice;

/* pointers to Alice declared here!! */

template<class T>
class Bob;

typedef Bob<int> Alice;

template<class T>
class Bob
{
};

VS2013 error C2371: 'Alice' : redefinition; different basic types

Why is this an error? Any way to work around it?

Upvotes: 2

Views: 90

Answers (3)

Jonathan Wakely
Jonathan Wakely

Reputation: 171403

It's ill-formed to declare something both as a class and as a typedef for a different class. Although class names and typedef names are interchangeable in many contexts, they are not always, e.g. it is possible to refer to the type as either Alice or class Alice (using what is called an elaborated-type-specifier) when it is a class, but that is not valid if Alice is a typedef name. That rule originates with C, where you can only use the elaborated-type-specifier and must declare a separate typedef to be able to say simply Alice.

The difference is important because the type has a "name for linkage purposes" which is the name used for name-mangling, which affects the symbols the linker sees.

If one file only saw the typedef name Alice and used that for the mangled name of a function such as void foo(Alice*) then you would not be able to link that function with other references to void foo(Bob<int>*) even though they should have the same mangled name.

For that reason it is necessary for the compiler to distinguish between typedefs (which are just aliases) and a type's "true name" (i.e. its name for linkage purposes).

The only workaround is to declare the types properly, so that the declaration of Alice as a typedef is used everywhere, i.e. replace the untrue class Alice; declaration with:

template<class T> class Bob;
typedef Bob<int> Alice;

Upvotes: 3

user966379
user966379

Reputation: 2993

If I assume this is right and there is statement

Alice obj;

How compiler will interpret the "Alice". In symbol table there would be 2 entry: one as a class and other as a template.

That's why it is giving error.

Upvotes: 0

sp2danny
sp2danny

Reputation: 7687

you can use inheritance as a possible workaround:

class Alice;

Alice* a1;

template<typename T>
class Bob {};

class Alice : public Bob<int> {} ;

Upvotes: 1

Related Questions