user2440822 user2440822 - 3 months ago 9
C++ Question

C++ class template as function return type

I'm working on a little project to understand how C++ templates work.
Basically, I have something like:

class Base{
public:
MyOperation<Base> operate(Base x){ return MyOperation<Base>(x); } //error here
};

//...

template<class B>
class MyOperation : public Base{
public:
B b;
MyOperation(B b_){ b = b_; }
};


When I try compiling my program, I get an error (Error C2143, missing ';' before '<'). Is it because I can't have MyOperation as return type of funcion operate()?

Thank you in advance.

Answer

The syntax for declaring a template is template<class B> (or equivalently, template<typename B>).

Also there is a circular reference: Base references MyOperation (return type and inside the operate function). So MyOperation would need to be defined before Base.

But MyOperation also references Base (base class).

For the base class, and for the use inside a function, a full definition is needed. But for the return type, an incomplete type is enough. So MyOperation would need to be predeclared before Base, like:

template<class B> class MyOperation;

And in addition, operate() needs to be defined (not declared) outside of class Base { ... }, after the definition of MyOperation. The correct code would be:

// pre-declaration of MyOperation
template<class B> class MyOperation;

// definition of Base class
class Base {
public:
    // declaration of Base::operate member function
    // MyOperation<Base> is incomplete type here
    MyOperation<Base> operate(Base x);
};   

// definition of MyOperation class template
template<class B>
class MyOperation : public Base{
public:
    B b;
    MyOperation(B b_){ b = b_; }
};

// definition ofBase::operate member function
inline MyOperation<Base> Base::operate(Base x) {
    return MyOperation<Base>(x);
}

Base::operate needs to be inline if the definition is in a header file, otherwise there will be multiple linker symbols if the header is included by multiple source files.

If it is not inline (better if it is a large function), then the definition should go in a source file.