编译模板实现时 VS 2017 崩溃
VS 2017 crashes when compiling template implementation
简而言之 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 没有出现在智能感知中。
有时 VS 完全崩溃(变灰并且 windows 显示消息:"Visual Studio 2017 stopped working"。有时它只显示游戏内消息:"C/C++ optimising compiler stopped working"
此外,在 HandleBase class 下或内联文件中定义其他函数时,我遇到了大量编译错误。正如我所说,如果所有函数都在它们的定义下实现,那么一切都编译得很好。我还尝试删除内联,这避免了崩溃,但给我带来了更多的编译错误。大多数完全是废话,例如:
2>c:\users\adrian\documents\visual studio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(75): 警告 C4346: "ThisHandleId": Abhängiger Name ist kein Typ
2>c:\users\adrian\documents\visual studio 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\visual studio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(76): error C2988: Unerkannte Vorlagendeklaration/-definition
2>c:\users\adrian\documents\visual studio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(76): error C2059: Syntaxfehler: ""
2>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 "; “对于“{”
2>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?
对于德国人的评论,我们深表歉意,但您大概能猜出其中一些人的意思。有 'depended name is not a type'、'syntax error ""' 和 'missing an ; before {'
之类的东西
此外,我认为首先删除内联并不是一个好主意。
如果您想知道代码的用途,请参阅此堆栈溢出问题的公认答案:
希望你能帮我解决这个奇怪的问题....
谢谢,
阿德里安
HandleID
是范围类型。因此,您将需要使用 HandleBased<Derived>::HandleID
。此外,由于 HandleID
是依赖类型。因此,您需要使用 typename HandleBased<Derived>::HandleID
.
使用:
template<class Derived>
inline typename HandleBased<Derived>::HandleID HandleBased<Derived>::ThisHandleId()
{
return id;
}
或者,使用尾随 return 类型(感谢@Angew):
template <class Derived>
auto HandleBase<Derived>::ThisHandleId() -> HandleId
{
return id;
}
这是可行的,因为尾随 return 类型在 class 的范围内。
简而言之 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 没有出现在智能感知中。
有时 VS 完全崩溃(变灰并且 windows 显示消息:"Visual Studio 2017 stopped working"。有时它只显示游戏内消息:"C/C++ optimising compiler stopped working"
此外,在 HandleBase class 下或内联文件中定义其他函数时,我遇到了大量编译错误。正如我所说,如果所有函数都在它们的定义下实现,那么一切都编译得很好。我还尝试删除内联,这避免了崩溃,但给我带来了更多的编译错误。大多数完全是废话,例如:
2>c:\users\adrian\documents\visual studio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(75): 警告 C4346: "ThisHandleId": Abhängiger Name ist kein Typ
2>c:\users\adrian\documents\visual studio 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\visual studio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(76): error C2988: Unerkannte Vorlagendeklaration/-definition
2>c:\users\adrian\documents\visual studio 2017\projects\mars base engine ecs 5\mars base engine ecs\handlebase.h(76): error C2059: Syntaxfehler: ""
2>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 "; “对于“{”
2>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?
对于德国人的评论,我们深表歉意,但您大概能猜出其中一些人的意思。有 'depended name is not a type'、'syntax error ""' 和 'missing an ; before {'
之类的东西此外,我认为首先删除内联并不是一个好主意。
如果您想知道代码的用途,请参阅此堆栈溢出问题的公认答案:
希望你能帮我解决这个奇怪的问题....
谢谢, 阿德里安
HandleID
是范围类型。因此,您将需要使用 HandleBased<Derived>::HandleID
。此外,由于 HandleID
是依赖类型。因此,您需要使用 typename HandleBased<Derived>::HandleID
.
使用:
template<class Derived>
inline typename HandleBased<Derived>::HandleID HandleBased<Derived>::ThisHandleId()
{
return id;
}
或者,使用尾随 return 类型(感谢@Angew):
template <class Derived>
auto HandleBase<Derived>::ThisHandleId() -> HandleId
{
return id;
}
这是可行的,因为尾随 return 类型在 class 的范围内。