编译模板实现时 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 的范围内。