Home > database >  Create an instance given pointer type in template
Create an instance given pointer type in template

Time:10-19

Is there a way to call the constructor of a class, given the pointer-type of that class type as the template parameter?

MyClass<AnotherClass*>  => how to call the default constructor of AnotherClass in MyClass?

This one does obviously not work (doesnt compile), because in GetNew the new T and the return type T don't fit together. What would be needed is some kind of "type dereferencing" to come to the class type, given the pointer type.

class AnotherClass
{};

template <class T>
class MyClass
{
public:
    // this does obviously not compile
    virtual T GetNew()
    {
        return new T; // how let T be AnotherClass* and to create an AnotherClass instance here?
    }

};

int main()
{
    // this does not compile:
    MyClass<AnotherClass*> tmp; // here, AnotherClass is **pointer** type
    AnotherClass* a = tmp.GetNew();

}

A workaround would be to use the class type as the template parameter and use poiter types as return types. But this changes the interface, so I would still like a solution to pointer template type.

class AnotherClass
{};

template <class T>
class MyClass2
{
public:
    virtual T* GetNew()
    {
        return new T;
    }

};

int main()
{
    // this does work:
    MyClass2<AnotherClass> tmp2; // here, AnotherClass is **not** pointer type
    AnotherClass* b = tmp2.GetNew();
}

Another workaround could be to use a factory or similar, but I would like to use the default constructor without additional helping structures.

CodePudding user response:

You can use std::remove_pointer to get the type pointed to.

Provides the member typedef type which is the type pointed to by T, or, if T is not a pointer, then type is the same as T.

E.g.

virtual T GetNew()
{
    return new std::remove_pointer_t<T>;
}

CodePudding user response:

If you require the parameter to MyClass to be a pointer, you can specialise it for pointers and leave it undefined for other types

template<typename>
class MyClass;

template<typename T>
class MyClass<T*>
{
public:
    virtual T* GetNew()
    {
        return new T;
    }
};

int main()
{
    // MyClass2<AnotherClass> tmp1; // compile error
    MyClass2<AnotherClass *> tmp2; // fine
    AnotherClass* b = tmp2.GetNew(); // GetNew returns the exact type parameter
}
  • Related