Estoy recibiendo un error de vinculador:
duplicate symbol __ZN5ENDF64FileILNS_7MF_enumE1EE4readEv in: Read.cpp.o Material.cpp.o
donde el nombre del símbolo duplicado es:
$ c++filt __ZN5ENDF64FileILNS_7MF_enumE1EE4readEv ENDF6::File::read()
Sé que no puedo definir la misma función en varios lugares, eso es lo que puede causar este error de vinculador. (He visto esta pregunta: ld: símbolo duplicado ) No creo que tenga la función read()
definida en varios lugares, pero el vinculador ( clang++
) dice que sí.
¿Dónde estoy duplicando el símbolo de read()
?
Mi estructura de código se ve así:
//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::read() { std::cout << "Reading into MF=1"<< std::endl; } #endif
No hay File.cpp
porque la clase File
tiene una plantilla. Todas las definiciones (y declaraciones) están en File.hpp
// Material.cpp #include "File.hpp" ... // Material.hpp #ifndef MATERIAL_HPP #define MATERIAL_HPP #include "File.hpp" ... #endif
Finalmente el código del conductor:
// Read.cpp #include "Material.hpp" #include "File.hpp" int main (){ ... }
Las especializaciones (completas) de una plantilla no son plantillas en sí mismas. Si está especializando la función, necesita declararla en el encabezado y proporcionar la implementación en una sola unidad de traducción, o bien hacer la definición en línea:
// Header [1] template class File { // ... void open(); }; template <> void File<1>::open(); // just declaration // Single .cpp template <> void File<1>::open() { ... }
Alternativamente:
// Header [2] template class File { // ... void open(); }; template <> inline void File<1>::open() { ... }