Reputation: 21803
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
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
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
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