Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

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?

like image 921
codeling Avatar asked Dec 16 '25 12:12

codeling


1 Answers

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>
{ };
like image 143
BoP Avatar answered Dec 19 '25 02:12

BoP



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!