Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Forward declaring a specific template instance

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

The first declaration says that MyClass is 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

  class A;

  class B
  {};

  using A = B;

One possible workaround would be to let MyClass really be a class, but derive it from the template instance.

class MyClass;

class MyClass : public Tmpl<SomeClass>
{ };
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading