使用新版本 Visual Studio 时已定义方法

Method already defined when using new version of Visual Studio

以下文件是我的 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 Studio 2015 中编译良好。我正在更新到 Visual Studio 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中定义了!这可能是什么原因造成的?

我的项目中当然还有很多其他代码和文件,但我已经在此处包含了我认为与错误相关的所有内容。

我认为您唯一缺少的是头文件中显式特化的声明。它必须出现在任何会隐式实例化 class 特化的点之前(因为函数是 virtual)。在存在显式特化声明的情况下,应禁止隐式实例化。

所以在DpElement定义后加入DpValue.h:

template<>
bool DpElement<DpValue>::operator==(DpValue::RElement const &Other) const;

它必须立即遵循 class 模板定义,以避免 class 的意外隐式实例化,这也可能隐式实例化虚拟成员函数的定义。

另见