为了简化Visual Studio 2017在编译此文件时崩溃:
#pragma once
/// @file
/// @brief Class mbe::HandleBase
#include <unordered_map>
//#include <cassert>
namespace mbe
{
template <class Derived>
class HandleBased abstract
{
public:
typedef unsigned long long int HandleID;
public:
HandleBased();
~HandleBased();
// Maybe rename to GetHandleId()?
HandleID ThisHandleId();
/*{
return id;
}*/
// Maybe rename to FindHandledObject
static Derived * FindPtr(HandleID id)
{
auto it = HandleBased::GetMap().find(id);
if (it == HandleBased::GetMap().end())
return nullptr;
// Should always be save
//assert(dynamic_cast<Derived *>(it->second));
return static_cast<Derived *>(it->second);
}
private:
static HandleID NextHandle()
{
// Every handle will get its own unique id
static HandleID next = 0;
return next++;
}
static std::unordered_map<HandleID, HandleBased *>& GetMap()
{
// Create the static map which will be used to keep track of the Derived handles and their ids
static std::unordered_map<HandleID, HandleBased *> map;
return map;
}
private:
HandleID id; // The id of this handle object
};
#pragma region Template Implementation
template<class Derived>
HandleBased<Derived>::HandleBased() :
id(NextHandle())
{
HandleBased::GetMap()[id] = this;
}
template<class Derived>
HandleBased<Derived>::~HandleBased()
{
auto it = HandleBased::GetMap().find(id);
HandleBased::GetMap().erase(it);
}
template<class Derived>
inline HandleID HandleBased<Derived>::ThisHandleId()
{
return id;
}
#pragma endregion
} // namespace mbe
当ThisHandleId()
函数直接定义在其定义之下时,它编译得很好。我的模板实现有问题吗?我注意到HandleID typedef没有显示在intellisense中。
有时VS完全崩溃(灰色并且Windows显示消息:“Visual Studio 2017停止工作”。有时它只显示游戏消息:“C / C ++优化编译器停止工作”
此外,在HandleBase类或内联文件中定义其他函数时,我遇到了大量的编译错误。正如我所说的,如果所有函数都在其定义之下实现,那么所有函数都可以正常编译。我还尝试了删除内联,以避免崩溃,但给了我更多的编译错误。 Mosty完全没有意义,例如:
2&gt; c:\ users \ adrian \ documents \ visual studio 2017 \ projects \ mars base engine ecs 5 \ mars base engine ecs \ handlebase.h(75):warning C4346:“ThisHandleId”:AbhängigerNameist kein Typ
2&gt; c:\ users \ adrian \ documents \ visual studio 2017 \ projects \ mars base engine ecs 5 \ mars base engine ecs \ handlebase.h(76):注意:Präfixmit“typename”zum Angeben eines Typs < / p>
2&gt; c:\ users \ adrian \ documents \ visual studio 2017 \ projects \ mars base engine ecs 5 \ mars base engine ecs \ handlebase.h(76):error C2988:Unerkannte Vorlagendeklaration / -definition
2&gt; c:\ users \ adrian \ documents \ visual studio 2017 \ projects \ mars base engine ecs 5 \ mars base engine ecs \ handlebase.h(76):error C2059:Syntaxfehler:“”
2&gt; c:\ users \ adrian \ documents \ visual studio 2017 \ projects \ mars base engine ecs 5 \ mars base engine ecs \ handlebase.h(76):error C2143:Syntaxfehler:Es fehlt“;” vor“{”
2&gt; c:\ users \ adrian \ documents \ visual studio 2017 \ projects \ mars base engine ecs 5 \ mars base engine ecs \ handlebase.h(76):error C2447:“{”:Funktionsheader fehlt - Parameterliste im alten Stil?
对于德国人的评论感到抱歉,但你可能会猜到他们中的一些评论。有像'依赖名称不是类型','语法错误“”和'缺少一个;在{'
之前另外,我不认为首先删除内联是一个好主意。
如果您想知道代码的用途,请在此堆栈溢出问题的加入答案中对其进行描述:Using shared_ptr for unique ownership (kind of) - is this good practice?
希望你能帮我解决这个奇怪的问题......
谢谢, 阿德里安
答案 0 :(得分:3)
HandleID
是范围类型。因此,您需要使用HandleBased<Derived>::HandleID
。此外,由于HandleID
是依赖类型。因此,您需要使用typename HandleBased<Derived>::HandleID
。
使用:
template<class Derived>
inline typename HandleBased<Derived>::HandleID HandleBased<Derived>::ThisHandleId()
{
return id;
}
或者,使用尾随返回类型(感谢@Angew):
template <class Derived>
auto HandleBase<Derived>::ThisHandleId() -> HandleId
{
return id;
}
这是有效的,因为尾随返回类型在类的范围内。