0

我有一个如下所示的 C++ 文件。



    // 用于文本调试
    #包括
    #包括
    //#包括
    #包括

    // stl 包括
    #包括
    #包括
    #包括



    // 快速固定大小内存分配器,用于快速节点内存管理
    #包括“fsa.h”

    // 可以禁用固定大小的内存分配器来比较性能
    // 如果你关闭它,则使用 std new 和 delete
    #define USE_FSA_MEMORY 1

    // 禁用调试信息有被截断行的警告
    // 出现在 stl 头文件中
    #pragma 警告(禁用:4786)

    // AStar 搜索类。UserState 是用户状态空间类型
    模板类 AStarSearch {

    上市:
        // 数据

        枚举{
            SEARCH_STATE_NOT_INITIALISED,
            SEARCH_STATE_SEARCHING,
            SEARCH_STATE_SUCCEEDED,
            SEARCH_STATE_FAILED,
            SEARCH_STATE_OUT_OF_MEMORY,
            SEARCH_STATE_INVALID
        };

        // 一个节点代表搜索中的可能状态
        // 用户提供的状态类型包含在此类型中

    上市:

        类节点{
        上市:

            节点*父;// 在搜索过程中用于记录后继节点的父节点
            节点 *child; // 用于搜索应用程序后查看反向搜索

            浮动 g; // 这个节点的成本 + 它的前辈(迄今为止的成本)
            浮动 h; // 到目标距离的启发式估计(启发式估计)
            浮动 f; // 前辈和自我和启发式的累积成本之和(costSoFar + 启发式估计)。

            节点():
                    父母(0),孩子(0),g(0.0f),h(0.0f),f(0.0f){
            }

             用户状态 m_用户状态;
        };

        // 为了对堆进行排序,STL 需要比较函数来让我们进行比较
        // 两个节点的 f 值

        类堆比较_f {
        上市:

            bool operator()(const Node *x, const Node *y) const {
                // 总启发式估计比较。
                返回 x->f > y->f;
            }
        };

    上市:
        // 方法

        // 构造函数只是初始化私有数据
        AStarSearch(int MaxNodes = 1000);

        // 随时调用取消搜索并释放所有内存
        无效的取消搜索();

        // 设置开始和目标状态
        无效 SetStartAndGoalStates(UserState &Start, UserState &Goal) ;

        // 使搜索前进一步
        无符号 int SearchStep() ;

        // 用户调用它来将后继者添加到后继者列表中
        // 扩展搜索边界时
        bool AddSuccessor(UserState &State) ;

        // 释放解节点
        // 这样做是为了在你完成后清理所有使用的节点内存
        // 搜索
        无效的自由解决方案节点();

        // 遍历解的函数

        // 获取起始节点
        用户状态 *GetSolutionStart() ;

        // 获取下一个节点
        用户状态 *GetSolutionNext() ;

        // 获取结束节点
        用户状态 *GetSolutionEnd() ;

        // 向后步进解决方案迭代器
        用户状态 *GetSolutionPrev() ;

        // 对于教育用途和调试,能够查看很有用
        // 每一步的打开和关闭列表,这里有两个函数允许这样做。

        用户状态 *GetOpenListStart() ;

        UserState *GetOpenListStart(float &f, float &g, float &h) ;

        用户状态 *GetOpenListNext() ;

        UserState *GetOpenListNext(float &f, float &g, float &h) ;

        用户状态 *GetClosedListStart() ;

        UserState *GetClosedListStart(float &f, float &g, float &h) ;

        用户状态 *GetClosedListNext() ;

        UserState *GetClosedListNext(float &f, float &g, float &h) ;

        // 获取步数

        int GetStepCount() ;

        无效的 EnsureMemoryFreed() ;

    私人的:
        // 方法

        // 当搜索失败或被取消以释放所有已使用的时调用
        // 记忆
        无效 FreeAllNodes() ;

        // 此调用由搜索类在搜索结束时进行。可能有很多节点
        // 搜索结束时仍然存在的创建。他们将被删除
        // 搜索结束后的例程
        无效 FreeUnusedNodes() ;

        // 节点内存管理
        节点 *AllocateNode() ;

        无效自由节点(节点*节点);

    私人的:
        // 数据

        // 堆(简单向量,但用作堆,参见 Steve Rabin 的游戏 gems 文章)
        std::vector m_OpenList;

        // 封闭列表是一个向量。
        std::vector m_ClosedList;

        // Successors 是一个由用户填写的向量,每个节点的后继类型
        // 被生成
        std::vector m_Successors;

        // 状态
        无符号整数 m_State;

        // 计算步数
        诠释 m_Steps;

        // 开始和目标状态指针
        节点 *m_Start;
        节点 *m_Goal;

        // 用于支持遍历解决方案链的指针。
        节点 *m_CurrentSolutionNode;

    #if USE_FSA_MEMORY
        // 记忆
        FixedSizeAllocator m_FixedSizeAllocator;
    #万一

        //调试:需要保留这两个迭代器
        // 用于用户 Dbg 函数
        类型名 std::vector::iterator iterDbgOpen;
        类型名 std::vector::iterator iterDbgClosed;

        // 调试:计算内存分配和空闲
        int m_AllocateNodeCount;

        布尔 m_CancelRequest;

    };

我无法编译它;我得到的错误是:

字段的类型“UserState”不完整

我怎样才能解决这个问题?

4

1 回答 1

3

您可以直接使用外部类的模板参数,无需多言。但是,当您A<X>使用某种类型进行实例化时,X您需要确保X在访问内部类型时该类型是完整的:

struct X;
A<X>::B a0; // ERROR: X is incomplete

struct X {};
A<X>::B a1; // OK: X is complete
于 2012-12-29T20:06:00.627 回答