C++11 VS2017在编译模板实现时崩溃
要使其简短,请在编译此文件时visual studio 2017崩溃:C++11 VS2017在编译模板实现时崩溃,c++11,templates,visual-studio-2017,inline,C++11,Templates,Visual Studio 2017,Inline,要使其简短,请在编译此文件时visual studio 2017崩溃: #pragma once /// @file /// @brief Class mbe::HandleBase #include <unordered_map> //#include <cassert> namespace mbe { template <class Derived> class HandleBased abstract { publi
#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
#pragma一次
///@file
///@BRIENT Class mbe::把手座
#包括
//#包括
名称空间mbe
{
模板
基于类句柄的抽象
{
公众:
typedef无符号长整型HandleID;
公众:
把手的();
~handlebase();
//可能重命名为GetHandleId()?
HandleID ThisHandleId();
/*{
返回id;
}*/
//可能重命名为FindHandleObject
静态派生*FindPtr(HandleID id)
{
auto it=handlebase::GetMap().find(id);
if(it==handlebase::GetMap().end())
返回空ptr;
//应该永远是拯救
//断言(动态_cast(it->second));
返回静态施法(它->秒);
}
私人:
静态HandleID NextHandle()
{
//每个句柄都将获得自己的唯一id
静态HandleID next=0;
返回next++;
}
静态std::无序的映射&GetMap()
{
//创建用于跟踪派生句柄及其ID的静态映射
静态std::无序的_图;
返回图;
}
私人:
HandleID;//此句柄对象的id
};
#pragma区域模板实现
模板
HandleBased::HandleBased():
id(NextHandle())
{
HandleBased::GetMap()[id]=此;
}
模板
把手座::~把手座()
{
auto it=handlebase::GetMap().find(id);
HandleBased::GetMap().擦除(它);
}
模板
内嵌HandleID HandleBase::ThisHandleId()
{
返回id;
}
#布拉格端区
}//名称空间mbe
当ThisHandleId()
函数在其定义的正下方定义时,它可以很好地编译。我的模板实现有问题吗?我注意到HandleID typedef没有在intellisense中显示
有时VS完全崩溃(变成灰色,windows显示消息:“Visual Studio 2017停止工作”。有时它只显示ingame消息:“C/C++优化编译器停止工作”
此外,在HandleBase类下或在内联文件中定义其他函数时,我会遇到大量编译错误。正如我所说,如果所有函数都在其定义下实现,则所有函数都可以正常编译。我还尝试过删除内联函数,以避免崩溃,但会产生更多编译错误。Mosty完全无意义,例如:
2> c:\users\adrian\documents\visualstudio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(75):警告C4346:“ThisHandleId”:Abhängiger名称是kein类型 2> c:\users\adrian\documents\visualstudio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(76):注:Präfix mit“typename”zum Angeben eines Typs 2> c:\users\adrian\documents\visualstudio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(76):错误C2988:Unerkannte vorlagendeklation/-definition 2> c:\users\adrian\documents\visualstudio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(76):错误C2059:Syntaxfehler:“ 2> c:\users\adrian\documents\visualstudio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(76):错误C2143:Syntaxfehler:Es fehlt“;“vor”{” 2> c:\users\adrian\documents\visualstudio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(76):错误C2447:“{”:Funktionsheader fehlt-Parameterliste im alten Stil
对不起,德语的评论,但你可能猜得到其中一些是什么意思。有一些东西像“依赖名称不是类型”、“语法错误”和“缺少一个;在{” 另外,我认为首先删除内联不是一个好主意 如果您想知道该代码的用途,请参阅此堆栈溢出问题的答案: 希望你能帮我解决这件奇怪的事情 谢谢,
Adrian
HandleID
是一个作用域类型。因此,您需要使用HandleBased::HandleID
。此外,由于HandleID
是一个依赖类型。因此,您需要使用typename HandleBased::HandleID
使用:
模板
内联类型名称HandleBased::HandleID HandleBased::ThisHandleId()
{
返回id;
}
或者,使用尾随返回类型(感谢@Angew):
模板
自动把手库::ThisHandleId()->HandleId
{
返回id;
}
这是有效的,因为尾部返回类型在类的范围内。@drescherjm以及crash我的意思是vs变灰并崩溃。windows显示消息:“Visual Studio 2017停止工作…”有趣的是,有时它不会完全崩溃,而是显示消息:优化编译器停止工作。如果将它添加到postLong快照中,但删除
#pragma区域
会有帮助吗?@Angew只是尝试了一下,不幸的是,没有^^^^与Q无关,但您是否意识到基于把手的
和哈ndleBased
每个人都有自己的地图
?似乎不需要键入地图
的vlaue到派生*
@Angew不,我不是-你是对的!(现在感觉有点迟钝了^^^),但感谢彼此,模板自动车把库::ThisHandleId()->HandleId
。尾部返回类型在类的范围内。
template<class Derived>
inline typename HandleBased<Derived>::HandleID HandleBased<Derived>::ThisHandleId()
{
return id;
}
template <class Derived>
auto HandleBase<Derived>::ThisHandleId() -> HandleId
{
return id;
}