header 中定义的模板函数,但仍然出现未解决的外部符号错误
Template function defined in header but still get unresolved external symbol error
我有一个简单的 class 可以写入文本文件以进行日志记录。它不是模板 class 但我想给它一个添加新条目的模板方法。这样我就不必为 signed char*、unsigned char*、std::string 等编写单独的方法。
构建时出现未解析的外部符号错误。
我研究了我的问题,了解到我要么必须在 header 文件中定义模板函数,要么在源文件的定义中使用 export 关键字。
使用 export 关键字没有用,所以我在 header 文件中定义了它,但我仍然收到错误。
我正在使用 Visual Studio 2019,C++17 作为语言标准。
Javelin::Log 在一个名为 'Javelin' 的项目中,该项目创建了一个静态库,项目 'Sygdas' 引用了该静态库。
Log.hpp(在标枪项目中)
#pragma once
#include "pch.hpp"
#include "Utility.hpp"
namespace Javelin
{
class Log
{
public:
Log(std::string filename);
~Log();
template<typename T>
void AddEntry(T entry)
{
m_file << GetCurrentTime() << " - " << entry << '\n';
}
private:
std::ofstream m_file;
};
}
Globals.hpp(在 Sygdas 项目中)
#pragma once
#include "Javelin.hpp" // includes Log.hpp
namespace Sygdas
{
inline Javelin::Log game_log{ "log.txt" };
}
Application.cpp(在 Sygdas 项目中)
#pragma once
#include "wxpch.hpp"
#include "Application.hpp"
#include "Javelin.hpp" // includes Log.hpp
#include "Globals.hpp"
namespace Sygdas
{
wxIMPLEMENT_APP(Application);
bool Application::OnInit()
{
game_log.AddEntry("Game Launched");
m_main_frame = new MainFrame();
return true;
}
}
我得到的错误是:
error LNK2019: unresolved external symbol "class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > __cdecl Javelin::GetTickCount(void)"
(?GetTickCount@Javelin@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
referenced in function "public: void __cdecl
Javelin::Log::AddEntry<char const *>(char const *)"
(??$AddEntry@PEBD@Log@Javelin@@QEAAXPEBD@Z)
如果我从 Application.cpp.
中删除 game_log.AddEntry("Game Launched");
行,它构建得很好
我理解为什么定义必须在header文件中;编译器需要知道模板的定义才能使用模板创建函数。
我不明白为什么 Application.cpp 在 Log.hpp 中没有定义,它通过 Javelin.hpp.
包含
感谢任何帮助。
GetCurrentTime() 定义
std::string GetCurrentTime()
{
time_t now{ time(&now) };
tm calendar{};
localtime_s(&calendar, &now);
char time_text[20]{};
strftime(time_text, sizeof(time_text), "%F %T", &calendar);
return std::string{ time_text };
}
Application.cpp 没有 GetCurrentTime() 的定义。
我有一个简单的 class 可以写入文本文件以进行日志记录。它不是模板 class 但我想给它一个添加新条目的模板方法。这样我就不必为 signed char*、unsigned char*、std::string 等编写单独的方法。
构建时出现未解析的外部符号错误。 我研究了我的问题,了解到我要么必须在 header 文件中定义模板函数,要么在源文件的定义中使用 export 关键字。 使用 export 关键字没有用,所以我在 header 文件中定义了它,但我仍然收到错误。
我正在使用 Visual Studio 2019,C++17 作为语言标准。 Javelin::Log 在一个名为 'Javelin' 的项目中,该项目创建了一个静态库,项目 'Sygdas' 引用了该静态库。
Log.hpp(在标枪项目中)
#pragma once
#include "pch.hpp"
#include "Utility.hpp"
namespace Javelin
{
class Log
{
public:
Log(std::string filename);
~Log();
template<typename T>
void AddEntry(T entry)
{
m_file << GetCurrentTime() << " - " << entry << '\n';
}
private:
std::ofstream m_file;
};
}
Globals.hpp(在 Sygdas 项目中)
#pragma once
#include "Javelin.hpp" // includes Log.hpp
namespace Sygdas
{
inline Javelin::Log game_log{ "log.txt" };
}
Application.cpp(在 Sygdas 项目中)
#pragma once
#include "wxpch.hpp"
#include "Application.hpp"
#include "Javelin.hpp" // includes Log.hpp
#include "Globals.hpp"
namespace Sygdas
{
wxIMPLEMENT_APP(Application);
bool Application::OnInit()
{
game_log.AddEntry("Game Launched");
m_main_frame = new MainFrame();
return true;
}
}
我得到的错误是:
error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl Javelin::GetTickCount(void)" (?GetTickCount@Javelin@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) referenced in function "public: void __cdecl Javelin::Log::AddEntry<char const *>(char const *)" (??$AddEntry@PEBD@Log@Javelin@@QEAAXPEBD@Z)
如果我从 Application.cpp.
中删除game_log.AddEntry("Game Launched");
行,它构建得很好
我理解为什么定义必须在header文件中;编译器需要知道模板的定义才能使用模板创建函数。 我不明白为什么 Application.cpp 在 Log.hpp 中没有定义,它通过 Javelin.hpp.
包含感谢任何帮助。
GetCurrentTime() 定义
std::string GetCurrentTime()
{
time_t now{ time(&now) };
tm calendar{};
localtime_s(&calendar, &now);
char time_text[20]{};
strftime(time_text, sizeof(time_text), "%F %T", &calendar);
return std::string{ time_text };
}
Application.cpp 没有 GetCurrentTime() 的定义。