I have a template that is just that - a very basic class template; something like:
Tmpl.h
template <typename Base>
class Tmpl: public Base
{
public:
Tmpl(): Base()
{
this->methodOfBase();
}
};
I would like to be able to forward-declare specialized versions of this Templ. I typically just store a (shared) pointer, so in my simple mind, all the compiler needs to know is that this is a pointer to a class; why am I not allowed to do this:
PublicClass.h
#pragma once
class MyClass;
class PublicClass {
// ....
private:
MyClass* test;
};
(I know pragma once isn't in the standard...)
PublicClass.cpp
#include "MyClass.h"
#include "Tmpl.h"
class SomeClass
{
public:
void methodOfBase()
{
}
};
using MyClass = Tmpl<SomeClass>;
int main()
{
PublicClass c;
return 0;
}
On Visual Studio (2022) I get an error: error C2371: 'MyClass': redefinition; different basic types.
I know that as a workaround I can change MyMethod.h to
#include "Tmpl.h"
class SomeClass;
using MyClass = Tmpl<SomeClass>;
void myMethod(MyClass* test);
But I do not understand why the fact that MyClass is using a template needs to be visible to the users of PublicClass (all users of that class need to know about it).
I get that the compiler needs to know if a class is templated, i.e., needs a template parameter. But in this case, MyClass is just an "instance" of a template, and shouldn't need special handling, or does it?
And what does the "different basic type" in the error refer to?
The first declaration says that
MyClassis a class. The second one says that it is not, it is an alias. Those are different.The problem is not realated to templates. You get the same error for
One possible workaround would be to let
MyClassreally be a class, but derive it from the template instance.