模板化函数的重新声明错误

时间:2013-04-10 20:58:13

标签: c++ templates

我有一个设置,其中模板化函数继承另一个模板化函数。

template <typename DataType>
class ClassBase
{ 
  virtual void InitModel(const cv::Mat& data) {};
}

template <typename DataType>
class ClassDerived : public ClassBase<DataType>
{
  void InitModel(const cv::Mat& data) {};
}

现在我尝试在实现文件中的ClassDerived中为InitModel实现两个特化和一个通用模板

template<>
void ClassDerived<float>::InitModel(const cv::Mat& data)
{
 // initialize some things
}

template<>
void ClassDervied<cv::Vec3b>::InitModel(const cv::Mat& data)
{
  // initialize some things
}

template<typename DataType>
void ClassDerived<DataType>::InitModel(const cv::Mat& data)
{
  // initialize some things
}

在我写这篇文章之前,我没有任何专业化,而且工作正常。 一旦我添加了专业化,我就会收到错误消息,说明重新声明了规范功能。奇怪的是,重新声明指出了相同的行号。在同一个文件中。 由于它在专业化之前工作正常,我希望文件不被读取两次。

那么,为什么在添加专业化后会立即弹出这样的错误?

错误是:

  

/other/workspace/perception/perception_kit/object_detection/include/perception_kit/object_detection/grimson_GMM_templated_impl.tpp:129:   多重定义   `perception_kit :: GrimsonGMMGen :: InitModel(cv :: Mat const&amp;)'   CMakeFiles / test_obj.dir / src目录/ object_detection_templated_test_platform.cpp.o:/other/workspace/perception/perception_kit/object_detection/include/perception_kit/object_detection/grimson_GMM_templated_impl.tpp:129:   首先在这里定义

问题是因为我试图派生一个模板化的类或其他东西吗?

现在我明白,对于一些人来说,这可能是一个微不足道的问题,但我在这里发布之前花了相当长的时间。

基类在BaseClass.h中(它作为抽象类实现) 派生类声明在DerivedClass.h中 派生类声明在DerivedClass.tpp中,并包含在DerivedClass.h中

2 个答案:

答案 0 :(得分:2)

您已经在标题中内嵌了基本模板代码(带有空体),因此您以后无法再次重新定义它。我怀疑这是你问题的根源,而不是专业。

答案 1 :(得分:1)

您需要声明您对这些类型有专门化。否则,当不同翻译单元中的编译器实例化模板时,它将基于主模板为成员函数生成代码。当您尝试将这些生成的函数与您的特化链接时,链接器将看到特殊化的多个定义。

// Header
template <typename T>
struct test {
   void f() {}
};
template <>
void test<int>::f();       // Declare the specialization

// Implementation (cpp, not included by client code)
template <>
void test<int>::f() { ... }

请注意,函数专精不再是模板,而是常规函数。如果不同的翻译单元包含函数的定义,那么它们将以多个翻译单元生成代码。如果你想这样做,那么你可以跳过专业化的声明并直接提供定义,但你需要将其设为inline

// Implementation (if in header/included by user code)
template <>
inline void test<int>::f() { ... }