C++ 错误 LNK1120:在静态函数内部调用时有 1 个未解析的外部
c++ error LNK1120: 1 unresolved externals on calling inside of static function
我在静态方法中调用模板函数时遇到问题。 这是我的代码: baseEvent.h
#ifndef BASE_EVENT_H
#define BASE_EVENT_H
#include <unordered_map>
#include <functional>
class baseEvent
{
public:
template<typename Sender,typename EventArgs>
using pureEvent = std::function<void(Sender, EventArgs)>;
template<typename pureEvent>
using eventMap = std::unordered_map<int, pureEvent>;
template<typename Sender, typename EventArgs>
struct Event
{
int AddEvent(pureEvent<Sender, EventArgs>);
void RemoveEvent(int);
void LaunchEvents(Sender, EventArgs);
private:
eventMap<pureEvent<Sender,EventArgs>> Events;
};
};
#endif
和基本事件.cpp
#include "baseEvent.h"
template <typename Sender, typename EventArgs>
int baseEvent::Event<Sender, EventArgs>::AddEvent(pureEvent<Sender, EventArgs> pure_event)
{
auto uniqeID = 0;
if (Events.rbegin() != Events.rend())
uniqeID = Events.rbegin()->first + 1;
Events.insert(std::make_pair(uniqeID, pure_event));
return uniqeID;
}
template <typename Sender, typename EventArgs>
void baseEvent::Event<Sender, EventArgs>::RemoveEvent(int uniqeID)
{
auto it = Events.find(uniqeID);
if (it != Events.end())
Events.erase(it);
}
template <typename Sender, typename EventArgs>
void baseEvent::Event<Sender, EventArgs>::LaunchEvents(Sender sender, EventArgs e)
{
if (Events.empty())return;
for (auto& singleEvent : Events)
{
singleEvent(sender, e);
}
}
另一个类.h
#include "baseEvent.h"
class anotherClass
{
public:
typedef baseEvent::pureEvent<nullptr_t, int> ballEvent;
static void Update();
static int AddOnChangeOwnerEvent(ballEvent);
static void RemoveOnChangeOwnerEvent(int);
static void LaunchOnChangeOwnerEvents(int);
private:
static baseEvent::Event<nullptr_t, int> OnChangeOwnerEvents;
};
另一个类.cpp
#include "anotherClass.h"
baseEvent::Event< nullptr_t, int> ball::OnChangeOwnerEvents;
void ball::Update()
{
LaunchOnChangeOwnerEvents(0);
//.
//.
//.
}
inline int anotherClass::AddOnChangeOwnerEvent(ballEvent ball_event)
{
return OnChangeOwnerEvents.AddEvent(ball_event);
}
inline void anotherClass::RemoveOnChangeOwnerEvent(int uniqeID)
{
return OnChangeOwnerEvents.RemoveEvent(uniqeID);
}
inline void anotherClass::LaunchOnChangeOwnerEvents(int event_args)
{
return OnChangeOwnerEvents.LaunchEvents(nullptr, event_args);
}
它给了我这个错误:
错误2 错误 LNK2019:未解析的外部符号"public: void __thiscall baseEvent::Event::LaunchEvents(std::nullptr_t,int)" (?LaunchEvents@?$Event@$$TH@baseEvent@@QAEX$$TH@Z) 引用于 功能"公共:静态空隙__cdecl otherClass::LaunchOnChangeOwnerEvents(int)" (?LaunchOnChangeOwnerEvents@ball@@SAXH@Z) E:\projects\ProFCEngine\SoccerAI\otherClass.obj SoccerAI
它应该工作正常,我做错了什么?
更新
如果我使用模板结构库事件::事件;启动更改所有者事件将修复,但如果我在我的主目录中执行此操作,我会再次出现错误。
#include "anotherClass.h"
int main()
{
anotherClass c;
ball::AddOnChangeOwnerEvent([](nullptr_t sender, int args)
{
std::cout << "here";
});
c.Update();
return 0;
}
使用模板类,不能只将实现放在源文件中。源文件不知道将使用哪些模板参数调用函数,因此它不会生成任何已编译的函数。因此,您会收到一个链接器错误,指出函数"未解析"。
您可以通过将实现移动到标头中来解决此问题,与类定义内联。
太久没读
最简单的解决方案是在baseEvent.cpp
末尾添加以下行
template struct baseEvent::Event<nullptr_t, int>;
答
假设您的 main 看起来像这样:
#include "anotherClass.h"
int main()
{
anotherClass c;
c.Update();
return 0;
}
当我们编译main时.cpp
g++ -std=c++11 -c main.cpp -o main.o
并检查我们的翻译部门需要/提供哪些符号:
$nm -gC main.o
0000000000000000 T main
U anotherClass::Update()
main.cpp
需要实施anotherClass::Update
。
让我们编译anotherClass.cpp
g++ -std=c++11 -c anotherClass.cpp -o anotherClass.o
再次检查我们的翻译部门需要/提供哪些符号:
$nm -gC anotherClass.o
[...]
0000000000000000 T anotherClass::Update()
U baseEvent::Event<decltype(nullptr), int>::LaunchEvents(decltype(nullptr), int)
[...]
anotherClass.cpp
提供了很多符号,为了清楚起见,我删除了它们。正如您在编译过程中所看到的anotherClass.cpp
LaunchEvents fornullptr_t, int
没有编译,因为编译器没有其定义。
当我们检查nm
baseEvent.o
时,我们会了解到它没有提供任何符号,也不需要任何符号。
nm -gC baseEvent.o
正如我之前所写的,问题是anotherClass.cpp
只有声明LaunchEvents
不是定义。
显式实例化
第一种方法是在baseEvent.cpp
中强制实例化此模板:
template struct baseEvent::Event<nullptr_t, int>;
如果我们在此类更改后检查baseEvent.o
我们将看到此翻译单元中将提供所需的符号:
$nm -gC baseEvent.o
[...]
0000000000000000 W baseEvent::Event<decltype(nullptr), int>::RemoveEvent(int)
0000000000000000 W baseEvent::Event<decltype(nullptr), int>::LaunchEvents(decltype(nullptr), int)
0000000000000000 W baseEvent::Event<decltype(nullptr), int>::LaunchEvents(baseEvent::Event<decltype(nullptr), int>, int)
0000000000000000 W baseEvent::Event<decltype(nullptr), int>::AddEvent(std::function<void (decltype(nullptr), int)>)
0000000000000000 W baseEvent::Event<decltype(nullptr), int>::AddEvent(std::function<void (baseEvent::Event<decltype(nullptr), int>, int)>)
[...]
将模板定义移动到标头
正如@qxz在他/她的回答中所述,您可以将模板实现移动到标题中。您可以在课后添加内联函数
#ifndef BASE_EVENT_H
#define BASE_EVENT_H
#include <unordered_map>
#include <functional>
class baseEvent
{
public:
[...]
template<typename Sender, typename EventArgs>
struct Event
{
int AddEvent(pureEvent<Sender, EventArgs>);
void RemoveEvent(int);
void LaunchEvents(Sender, EventArgs);
private:
eventMap<pureEvent<Sender,EventArgs>> Events;
};
};
[...]
template <typename Sender, typename EventArgs>
inline void baseEvent::Event<Sender, EventArgs>::LaunchEvents(Sender sender, EventArgs e)
{
if (Events.empty())return;
for (auto& singleEvent : Events)
{
singleEvent.second(sender, e);
}
}
#endif
或者在类定义中添加实现
class baseEvent
{
public:
[...]
template<typename Sender, typename EventArgs>
struct Event
{
[...]
void LaunchEvents(Sender sender, EventArgs e)
{
if (Events.empty())return;
for (auto& singleEvent : Events)
{
singleEvent.second(sender, e);
}
}
private:
eventMap<pureEvent<Sender,EventArgs>> Events;
};
};
如果这样做,将在anotherClass.o
中提供实现:
$ nm -gC anotherClass.o | grep LaunchEvent
0000000000000000 W baseEvent::Event<decltype(nullptr), int>::LaunchEvents(decltype(nullptr), int)
0000000000000000 W baseEvent::Event<decltype(nullptr), int>::LaunchEvents(baseEvent::Event<decltype(nullptr), int>, int)
- C++、错误LNK1120和LNK2001中未解析的外部符号
- Visual Studio 2010 - C++ 致命错误 LNK1120: 1 个未解析的外部
- LNK2019和LNK1120错误,未解析的外部和未解析的符号
- 错误LNK1120:未解决的外部
- 如何在我的指针和阵列功能中修复未解决的外部错误-LNK2019和LNK1120
- C++ 错误 LNK1120:在静态函数内部调用时有 1 个未解析的外部
- c++中的静态构造函数和致命错误LNK1120:1个未解析的外部
- SDL错误LNK1120:1未解决的外部
- QT错误:LNK1120:1未解决的外部Main.OBJ:-1:错误:LNK2019运行QMAKE
- Qt LNK1120未解析的外部
- LNK1120:Visual Studio 2012 中 1 个未解析的外部
- 编译任何内容时出现奇怪的错误,VS 2010:致命错误LNK1120:1个未解决的外部
- 错误 LNK2019:未解析的外部和LNK1120:1 个未解析的外部
- 操作员过载未解决的外部错误LNK1120、LNK2019
- visual C++LNK1120致命错误:1个未解析的外部
- 致命错误LNK1120:1 个未解析的外部 & 错误 LNK2019:函数___tmainCRTStartup中引用_main未解析的外部符号
- Ogre 3D错误-LNK1120:1个未解析的外部
- 致命错误LNK1120:8个未解析的外部
- LNK2019:函数"函数"中'symbol'引用未解析的外部符号;致命错误 LNK1120:1 未解析的外部
- c++静态变量在Visual Studio中产生致命错误LNK1120: 1未解析的外部