3

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

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&)' 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

4

2 回答 2

2

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

于 2013-04-10T21:08:18.683 回答
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() { ... }
于 2013-04-10T21:20:36.707 回答