Nico van Bentum
Nico van Bentum

Reputation: 347

Returning Derived templated class as Base class pointer

class Base {
public:
    template<typename T>
    static Base* construct() {
        return new Derived<T>();
    }
};

template<typename T>
class Derived : public Base {
public:
    Derived() {}
};

That code generates a compile error (VS Studio 2017):

syntax error: unexpected token 'identifier', expected 'type specifier'

Is this invalid C++? Is this pattern not possible?

Upvotes: 0

Views: 72

Answers (3)

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38405

Either split the declaration and implementation:

class Base {
public:
    static Base* construct();
};

template<typename T>
class Derived : public Base {
public:
    Derived() {}
};

template<typename T>
Base* Base::construct() {
    return new Derived<T>();
}

Or use the template magic:

template<typename Derived>
class Base {
public:
    static Base* construct() {
        return new Derived();
    }
};

template<typename T>
class Derived : public Base<Derived<T>> {
public:
    Derived() {}
};

Upvotes: 0

Paul Evans
Paul Evans

Reputation: 27567

Declare Base as:

class Base {
public:
    template<typename T>
    static Base* construct();
}

Then declare Derived:

template<typename T>
class Derived : public Base {
public:
    Derived() {}
};

Then define Base::construct:

static Base* Base::construct() {
    return new Derived<T>();
}

The compiler needs a full definition of Derived before it can deal with the new in Base::construct.

Upvotes: 5

idailylife
idailylife

Reputation: 174

Try forward declare class Derived before Base.

template <typename T>
class Derived;

class Base {
//...
}; 

The compiler doesn't know what is Derived in return new Derived<T>() as it is declared afterwards. `

Upvotes: 0

Related Questions