我有一个设置,其中模板化函数继承另一个模板化函数。
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中
答案 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() { ... }