C++:避免重复的符号链接器错误

C++: Avoiding duplicate symbol linker error

本文关键字:符号链接 错误 C++      更新时间:2023-10-16

我收到一个链接器错误:

duplicate symbol __ZN5ENDF64FileILNS_7MF_enumE1EE4readEv in:
    Read.cpp.o
    Material.cpp.o

其中重复符号名称为:

$ c++filt __ZN5ENDF64FileILNS_7MF_enumE1EE4readEv
  ENDF6::File<(ENDF6::MF_enum)1>::read()

我知道我不能在多个地方定义同一个函数——这就是导致链接器错误的原因。(我看到过这个问题:ld:重复符号)我不认为我在多个地方定义了read()函数,但链接器(clang++)说我定义了。

我在哪里复制read()符号?

我的代码结构如下:

//MFs.hpp
#ifndef MFS_HPP
#define MFS_HPP
enum class MF_enum {
...
}
#endif

//File.hpp
#ifndef FILE_HPP
#define FILE_HPP
#include "MFs.hpp"
// Definition of class File
template<>
class File {
...
}
// Definition of File<...>::read() function
template <>
void File<1>::read()
{
    std::cout << "Reading into MF=1"<< std::endl;
}
#endif

没有File.cpp,因为File类是模板化的。所有定义(和声明)均在File.hpp

// Material.cpp
#include "File.hpp"
...
// Material.hpp
#ifndef MATERIAL_HPP
#define MATERIAL_HPP
#include "File.hpp"
...
#endif

最后是驱动程序代码:

// Read.cpp
#include "Material.hpp"
#include "File.hpp"
int main (){
...
}

(完整)模板的专门化不是模板本身。如果您正在专门化函数,那么您需要在头中声明它并在单个翻译单元中提供实现,或者使定义内联:

// Header [1]
template <int>
class File {
   // ...
   void open();
};
template <>
void File<1>::open(); // just declaration
// Single .cpp
template <>
void File<1>::open() { ... }

或者:

// Header [2]
template <int>
class File {
   // ...
   void open();
};
template <>
inline void File<1>::open() { ... }