模板化函数的重声明错误

Redeclaration error for a templated function

本文关键字:声明 错误 函数      更新时间:2023-10-16

我有一个模板化函数继承另一个模板化函数的设置。

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
}

在我写这篇文章之前,我没有任何专门化,它工作得很好。一旦我添加了专门化,我就会得到一个错误,说有一个规范函数的重新声明。奇怪的是,重新声明指向相同的行号。在同一个文件中。由于它在专门化之前工作得很好,我希望文件不会被读取两次。

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

错误是:

/其他/workspace/认知/perception_kit/object_detection/include/perception_kit/object_detection/grimson_GMM_templated_impl.tpp: 129:的多重定义"perception_kit:: GrimsonGMMGen:: InitModel(简历::垫const&) 'CMakeFiles/test_obj.dir/src/object_detection_templated_test_platform.cpp.o:/其他/workspace/认知/perception_kit/object_detection/include/perception_kit/object_detection/grimson_GMM_templated_impl.tpp: 129:第一次定义在这里

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

现在我明白,对于一些人来说,这可能是一个微不足道的问题,但我花了相当多的时间才把它贴在这里。

基类在basecclass .h中(它作为抽象类实现)派生类声明在DerivedClass.h中派生类声明在DerivedClass中。包含在DerivedClass.h

您已经在header中内联定义了基本模板代码(带有空主体),因此以后不能再重新定义它。

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

// 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() { ... }