使用模板有什么问题?

时间:2016-12-06 10:38:03

标签: c++ templates

这是我第一次在课堂上使用Template。这是我的尝试。

MyCairoControl.h:

#ifndef _MYCAIROCONTROL_
#define _MYCAIROCONTROL_

template<class T>
class MyCairoControl : public IControl 
{
private:
    T *pPlug;

public:
    MyCairoControl(T *plug, IRECT container);
    ~MyCairoControl();
};

#endif // !_MYCAIROCONTROL_

MyCairoControl.cpp:

#include "MyCairoControl.h"

MyCairoControl::MyCairoControl(T *plug, IRECT container) : IControl(plug, container), pPlug(plug) {
       // t->somethings();
}
MyCairoControl::~MyCairoControl() {

}

但它说&#34; T&#34;未定义,所以我无法使用该CTOR。不是在课堂上使用模板的正确方法吗?

2 个答案:

答案 0 :(得分:3)

由于MyCairoControl类模板,因此其方法定义也必须是模板,与类的模板参数匹配:

template <class T>
MyCairoControl<T>::MyCairoControl(T *plug, IRECT container){
     /* ... */
}

template <class T>
MyCairoControl<T>::~MyCairoControl() { 
     /* ... */
}

wandbox example

这也意味着定义总是必须在编译期间可用,而不是链接 - 它们需要存在于头文件中。

This article (&#34;如何在.h文件中定义模板类并在.cpp文件中实现&#34;)对该问题进行全面解释。

答案 1 :(得分:1)

您需要在实现文件中重新声明T作为模板类型名称:

#include "MyCairoControl.h"

template<class T>
MyCairoControl<T>::MyCairoControl(T *plug, IRECT container) : IControl(plug, container), pPlug(plug) {
       // t->somethings();
}


template<class T>
MyCairoControl<T>::~MyCairoControl() {

}

最初的问题是双重问题。首先,T作为符号需要被称为模板参数。添加到实现签名的template<class T>行执行此操作 - 它定义了T的含义。其次,您需要意识到构造函数和析构函数(实际上是任何成员)所属的类型不再是MyCairoControl而是MyCairoControl<T>。范围解析运算符的左侧现在需要是。

还有一个值得注意的问题。就目前而言,类成员的实现与标题位于一个单独的文件中,这可能会产生问题。该类的消费者将包括标题而不是源文件,因此他们将无法使用该模板 - 例如,如果他们尝试使用MyCairoControl<Foo>,他们将得到未解决的符号错误。如果您知道将用于T的类型,则可以修复此问题。具体而言,如果您在MyCairoControl.cpp中声明专业化,如下所示:

template <>
class MyCairoControl<Foo>;

template <>
class MyCairoControl<Bar>;

任何人都可以使用MyCairoControl<Foo>MyCairoControl<Bar>,但尝试使用MyCairoControl<OtherType>仍会提供未解决的外部符号错误,直到您为其添加前向声明。