C ++类模板作为函数返回类型

时间:2016-09-01 19:38:50

标签: c++ templates class-template

我正在开展一个小项目,以了解C ++模板的工作原理。 基本上,我有类似的东西:

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_; }
};

当我尝试编译程序时,出现错误(错误C2143,缺少&#39 ;;&#39;之前&#39;&lt;&#;;)。是因为我不能将MyOperation作为funcion的返回类型操作()?

提前谢谢。

1 个答案:

答案 0 :(得分:3)

声明模板的语法是template<class B>(或等效地,template<typename B>)。

还有一个循环引用:Base引用MyOperation(返回类型和operate函数内部)。因此需要在MyOperation之前定义Base

但是MyOperation也引用了Base(基类)。

对于基类,以及在函数内部使用,需要完整的定义。但对于返回类型,不完整类型就足够了。因此MyOperation需要在Base之前预先声明,例如:

template<class B> class MyOperation;

此外,在operate()的定义之后,class Base { ... }需要在MyOperation之外定义(未声明)。正确的代码是:

// 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需要内联,否则如果多个源文件包含头,则会有多个链接器符号。

如果它不是内联的(如果它是一个大函数则更好),那么定义应该放在源文件中。