C++ 标头中定义了模板函数,但仍获取未解析的外部符号错误

C++ 标头中定义了模板函数,但仍获取未解析的外部符号错误,c++,templates,linker-errors,C++,Templates,Linker Errors,我有一个简单的类,它可以写入文本文件进行日志记录。它不是一个模板类,但我想给它一个模板方法来添加一个新条目。这样我就不必为有符号字符*、无符号字符*、std::string等编写单独的方法 我在构建时遇到未解决的外部符号错误。 我研究了我的问题,了解到要么在头文件中定义模板函数,要么在源文件的定义中使用export关键字。 使用export关键字不起作用,所以我在头文件中定义了它,但仍然会出现错误 我使用Visual Studio 2019和C++17作为语言标准。 Javelin::Log位于

我有一个简单的类,它可以写入文本文件进行日志记录。它不是一个模板类,但我想给它一个模板方法来添加一个新条目。这样我就不必为有符号字符*、无符号字符*、std::string等编写单独的方法

我在构建时遇到未解决的外部符号错误。 我研究了我的问题,了解到要么在头文件中定义模板函数,要么在源文件的定义中使用export关键字。 使用export关键字不起作用,所以我在头文件中定义了它,但仍然会出现错误

我使用Visual Studio 2019和C++17作为语言标准。 Javelin::Log位于一个名为“Javelin”的项目中,该项目创建了一个静态库,项目“Sygdas”引用了该库

Log.hpp(标枪项目中)


应用程序.cpp(在Sygdas项目中)

我得到的错误是:

错误LNK2019:未解析的外部符号“类
std::basic_string _cdecl Javelin::GetTickCount(void)”
(?GetTickCount@Javelin@@是吗?AV?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@XZ)
在函数“public:void\u cdecl”中引用
标枪::日志::加法器(字符常量*)”
(??$AddEntry@PEBD@Log@Javelin@@QEAAXPEBD@Z)

如果我删除行
game_log.AddEntry(“game-launted”)来自Application.cpp

我理解为什么定义必须在头文件中;为了使用模板创建函数,编译器需要知道模板的定义。 我不明白为什么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()的定义。

Javelin是否有需要链接的
.lib
文件?Javelin创建的是.lib文件。我编写了一个非模板方法来创建条目。我能够在Sygdas中调用该方法,并成功地构建它,应用程序将正确地写入文本文件。换句话说,Sygdas确实与标枪有正确的联系。
GetTickCount
的定义(或声明)在哪里?我不知道。这不是我写的东西。我猜它是在GetCurrentTime()运行时被调用的。我将在post中添加GetCurrentTime()定义。
#pragma once
#include "Javelin.hpp" // includes Log.hpp

namespace Sygdas
{
    inline Javelin::Log game_log{ "log.txt" };
}
#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;
    }
}
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 };
}