如何解决这个一个或多个多重定义符号发现错误?
How can I resolve this one or more multiply defined symbol found error?
以下项目中的错误是什么?
main.cpp
#include "template_specialization_conflict_test.hpp"
int main()
{
std::cout << utils::my_template_function(0.555);
std::cout<<utils::my_template_function<double>(0.555);
return 0;
}
template_specialization_conflict_test.hpp
#ifndef UTILS__UTILS__UTILS__UTILS
#define UTILS__UTILS__UTILS__UTILS
#include <iostream>
namespace utils
{
// A generic function
template <class T>
T my_template_function(T parameter)
{
std::cout << "function template";
std::cout << parameter;
return parameter;
}
// Template Specialization
// A function specialized for double data type
template <>
double my_template_function<double>(double parameter)
{
std::cout << "function specialization on double";
std::cout << parameter;
return parameter;
}
}
#endif
template_specialization_conflict_test.cpp
#include "template_specialization_conflict_test.hpp"
namespace utils
{
//empty
}
错误
>------ Rebuild All started: Project: template_specialization_conflict_test, Configuration: x64-Debug ------
[1/1] Cleaning all built files...
Cleaning... 2 files.
[1/3] Building CXX object CMakeFiles\template_specialization_conflict_test.dir\main.cpp.obj
[2/3] Building CXX object CMakeFiles\template_specialization_conflict_test.dir\template_specialization_conflict_test.cpp.obj
[3/3] Linking CXX executable template_specialization_conflict_test.exe
FAILED: template_specialization_conflict_test.exe
cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio19\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\template_specialization_conflict_test.dir --rc=C:\PROGRA~2\WI3CF2~1\bin.0.17763.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\bin.0.17763.0\x64\mt.exe --manifests -- "C:\PROGRA~2\Microsoft Visual Studio19\Professional\VC\Tools\MSVC.29.30133\bin\Hostx64\x64\link.exe" /nologo CMakeFiles\template_specialization_conflict_test.dir\template_specialization_conflict_test.cpp.obj CMakeFiles\template_specialization_conflict_test.dir\main.cpp.obj /out:template_specialization_conflict_test.exe /implib:template_specialization_conflict_test.lib /pdb:template_specialization_conflict_test.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
LINK Pass 1: command "C:\PROGRA~2\Microsoft Visual Studio19\Professional\VC\Tools\MSVC.29.30133\bin\Hostx64\x64\link.exe /nologo CMakeFiles\template_specialization_conflict_test.dir\template_specialization_conflict_test.cpp.obj CMakeFiles\template_specialization_conflict_test.dir\main.cpp.obj /out:template_specialization_conflict_test.exe /implib:template_specialization_conflict_test.lib /pdb:template_specialization_conflict_test.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\template_specialization_conflict_test.dir/intermediate.manifest CMakeFiles\template_specialization_conflict_test.dir/manifest.res" failed (exit code 1169) with the following output:
C:\Users\pc\source\repos\template_specialization_conflict_test\out\build\x64-Debug\main.cpp.obj : error LNK2005: "double __cdecl utils::my_template_function<double>(double)" (??$my_template_function@N@utils@@YANN@Z) already defined in template_specialization_conflict_test.cpp.obj
C:\Users\pc\source\repos\template_specialization_conflict_test\out\build\x64-Debug\template_specialization_conflict_test.exe : fatal error LNK1169: one or more multiply defined symbols found
ninja: build stopped: subcommand failed.
Rebuild All failed.
我该如何解决这个问题?
How can I fix this?
您可以通过 adding/using 专业化的关键字 inline
来解决此问题,因此专业化看起来像:
//note the keyword inline in the below specialization
template <> inline
double my_template_function<double>(double parameter)
{
std::cout << "function specialization on double";
std::cout << parameter;
return parameter;
}
可以看出这是有效的 here。
解决此问题的第二种 方法是将您的专业化移动到源文件而不是 header。所以你的 template_specialization_conflict_test.cpp 看起来像:
template_specialization_conflict_test.cpp
#include "template_specialization_conflict_test.hpp"
namespace utils
{
// Template Specialization
// A function specialized for double data type
template <>
double my_template_function<double>(double parameter)
{
std::cout << "function specialization on double";
std::cout << parameter;
return parameter;
}
}
程序运行正常 here and here(with gcc and clang)。
以下项目中的错误是什么?
main.cpp
#include "template_specialization_conflict_test.hpp"
int main()
{
std::cout << utils::my_template_function(0.555);
std::cout<<utils::my_template_function<double>(0.555);
return 0;
}
template_specialization_conflict_test.hpp
#ifndef UTILS__UTILS__UTILS__UTILS
#define UTILS__UTILS__UTILS__UTILS
#include <iostream>
namespace utils
{
// A generic function
template <class T>
T my_template_function(T parameter)
{
std::cout << "function template";
std::cout << parameter;
return parameter;
}
// Template Specialization
// A function specialized for double data type
template <>
double my_template_function<double>(double parameter)
{
std::cout << "function specialization on double";
std::cout << parameter;
return parameter;
}
}
#endif
template_specialization_conflict_test.cpp
#include "template_specialization_conflict_test.hpp"
namespace utils
{
//empty
}
错误
>------ Rebuild All started: Project: template_specialization_conflict_test, Configuration: x64-Debug ------
[1/1] Cleaning all built files...
Cleaning... 2 files.
[1/3] Building CXX object CMakeFiles\template_specialization_conflict_test.dir\main.cpp.obj
[2/3] Building CXX object CMakeFiles\template_specialization_conflict_test.dir\template_specialization_conflict_test.cpp.obj
[3/3] Linking CXX executable template_specialization_conflict_test.exe
FAILED: template_specialization_conflict_test.exe
cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio19\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\template_specialization_conflict_test.dir --rc=C:\PROGRA~2\WI3CF2~1\bin.0.17763.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\bin.0.17763.0\x64\mt.exe --manifests -- "C:\PROGRA~2\Microsoft Visual Studio19\Professional\VC\Tools\MSVC.29.30133\bin\Hostx64\x64\link.exe" /nologo CMakeFiles\template_specialization_conflict_test.dir\template_specialization_conflict_test.cpp.obj CMakeFiles\template_specialization_conflict_test.dir\main.cpp.obj /out:template_specialization_conflict_test.exe /implib:template_specialization_conflict_test.lib /pdb:template_specialization_conflict_test.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
LINK Pass 1: command "C:\PROGRA~2\Microsoft Visual Studio19\Professional\VC\Tools\MSVC.29.30133\bin\Hostx64\x64\link.exe /nologo CMakeFiles\template_specialization_conflict_test.dir\template_specialization_conflict_test.cpp.obj CMakeFiles\template_specialization_conflict_test.dir\main.cpp.obj /out:template_specialization_conflict_test.exe /implib:template_specialization_conflict_test.lib /pdb:template_specialization_conflict_test.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\template_specialization_conflict_test.dir/intermediate.manifest CMakeFiles\template_specialization_conflict_test.dir/manifest.res" failed (exit code 1169) with the following output:
C:\Users\pc\source\repos\template_specialization_conflict_test\out\build\x64-Debug\main.cpp.obj : error LNK2005: "double __cdecl utils::my_template_function<double>(double)" (??$my_template_function@N@utils@@YANN@Z) already defined in template_specialization_conflict_test.cpp.obj
C:\Users\pc\source\repos\template_specialization_conflict_test\out\build\x64-Debug\template_specialization_conflict_test.exe : fatal error LNK1169: one or more multiply defined symbols found
ninja: build stopped: subcommand failed.
Rebuild All failed.
我该如何解决这个问题?
How can I fix this?
您可以通过 adding/using 专业化的关键字 inline
来解决此问题,因此专业化看起来像:
//note the keyword inline in the below specialization
template <> inline
double my_template_function<double>(double parameter)
{
std::cout << "function specialization on double";
std::cout << parameter;
return parameter;
}
可以看出这是有效的 here。
解决此问题的第二种 方法是将您的专业化移动到源文件而不是 header。所以你的 template_specialization_conflict_test.cpp 看起来像: template_specialization_conflict_test.cpp
#include "template_specialization_conflict_test.hpp"
namespace utils
{
// Template Specialization
// A function specialized for double data type
template <>
double my_template_function<double>(double parameter)
{
std::cout << "function specialization on double";
std::cout << parameter;
return parameter;
}
}
程序运行正常 here and here(with gcc and clang)。