以下文件是我的C++项目的一部分。
// DpValue.h
class DpValue {
public:
class RElement {
public:
virtual bool operator==(RElement const &Other) const = 0;
};
};
template<class T>
class DpElement : public DpValue::RElement {
public:
virtual bool operator==(DpValue::RElement const &Other) const { ... }
};// DpValue.cpp
#include <DpValue.h>
template<>
bool DpElement<DpValue>::operator==(DpValue::RElement const &Other) const { ... }// DpType.cpp
#include <DpValue.h>
...它在Visual 2015中编译得很好。我正在更新到Visual 2022,在这里我得到了以下链接器错误:
Code: LNK2005
Description: "public: virtual bool __cdecl DpElement<class DpValue>::operator==(class DpValue::RElement const &)const " (??8?$DpElement@VDpValue@@@@UEBA_NAEBVRElement@DpValue@@@Z) already defined in DpKernel64Dbg.lib(DpValue.obj)
Project: DpDiagram
File: DpKernel64Dbg.lib(DpType.obj)据我理解,该方法是在DpValue.obj中定义的,这是正确的。但是,在DpType.obj中再次定义了它!是什么原因造成的?
当然,我的项目中还有很多其他代码和文件,但是我已经包含了我认为与错误相关的所有内容。
发布于 2022-03-09 21:04:03
我认为您唯一缺少的是头文件中显式专门化的声明。它必须出现在隐式实例化类专门化的任何点之前(因为函数是virtual)。在显式专门化声明存在的情况下,应该禁止隐式实例化。
因此,在DpValue.h的定义之后添加DpElement
template<>
bool DpElement<DpValue>::operator==(DpValue::RElement const &Other) const;它必须立即遵循类模板定义,以避免类的意外隐式实例化,这也可能隐式实例化虚拟成员函数的定义。
另见Explicit specialization of member function template in source file。
https://stackoverflow.com/questions/71415131
复制相似问题