C ++:模板化类指针转换

时间:2015-12-09 01:02:10

标签: c++

我在一个模板化的类中遇到了一个错误,我创建了一个指向以后创建的子项的指针。产生的错误有点奇怪,因为我从未见过它。

代码:

template <size_t maxObjects, size_t maxDepth, bool canDelete = false, size_t depth = 0>
struct DynamicQT
{
public:
    DynamicQT(const Aabb2& aabb) : aabb(aabb)
    {

    }
    ~DynamicQT()
    {
        clearObjects();
        destroyBranches();
    }
    void insert(Object* object)
    {
        if (hasBranches())
        {
            if (object->getAABB().overlaps(tl->aabb)) tl->insert(object);
            if (object->getAABB().overlaps(tr->aabb)) tr->insert(object);
            if (object->getAABB().overlaps(bl->aabb)) bl->insert(object);
            if (object->getAABB().overlaps(br->aabb)) br->insert(object);
        }
        else objects[(size_t)object] = object;
    }
    void remove(Object* object)
    {
        if (hasBranches())
        {
            if (object->getAABB().overlaps(tl->aabb)) tl->remove(object);
            if (object->getAABB().overlaps(tr->aabb)) tr->remove(object);
            if (object->getAABB().overlaps(bl->aabb)) bl->remove(object);
            if (object->getAABB().overlaps(br->aabb)) br->remove(object);
        }
        else
        {
            auto result = objects.find((size_t)object);
            if (result != objects.end())
                objects.erase((size_t)object);
        }
    }
    void query(const Aabb2& queryRect, std::vector<Object*>& outVec)
    {
        std::map<size_t, Object*> outMap;
        query(queryRect, outMap);
        if (depth == 0)
        {
            for (const auto& item : objects)
                outVec.push_back(item.second);
        }
    }
    void update()
    {
        throw;
    }
public:
    void query(const Aabb2& queryRect, std::map<size_t, Object*>& outMap)
    {
        if (hasBranches())
        {
            if (queryRect.overlaps(tl->aabb)) tl->query(queryRect, outMap);
            if (queryRect.overlaps(tr->aabb)) tr->query(queryRect, outMap);
            if (queryRect.overlaps(bl->aabb)) bl->query(queryRect, outMap);
            if (queryRect.overlaps(br->aabb)) br->query(queryRect, outMap);
        }
        else outMap.insert(objects.begin(), objects.end());
    }
    void clearObjects()
    {
        if (canDelete)
        {
            for (const auto& obj : objects)
                if (obj.second) delete obj.second;
        }
        objects.clear();
    }
    void createBranches()
    {
        if (!hasBranches() && depth < maxDepth)
        {
            Vector2 half = aabb.halfWidths();
            Aabb2 a(aabb.pos, half);
            Aabb2 b(aabb.pos.addX(half.x), half);
            Aabb2 c(aabb.pos.addY(half.y), half);
            Aabb2 d(aabb.center(), half);
            tl = new DynamicQT<maxObjects, maxDepth, canDelete, depth + 1>(a);
            tr = new DynamicQT<maxObjects, maxDepth, canDelete, depth + 1>(b);
            bl = new DynamicQT<maxObjects, maxDepth, canDelete, depth + 1>(c);
            br = new DynamicQT<maxObjects, maxDepth, canDelete, depth + 1>(d);
        }
    }
    void passObjectsToBranches()
    {
        if (hasBranches())
        {
            Object* obj = nullptr;
            for (const auto& item : objects)
            {
                obj = item.second;
                if (obj->getAABB().overlaps(tl->aabb)) tl->insert(obj);
                if (obj->getAABB().overlaps(tr->aabb)) tr->insert(obj);
                if (obj->getAABB().overlaps(bl->aabb)) bl->insert(obj);
                if (obj->getAABB().overlaps(br->aabb)) br->insert(obj);
            }
            clearObjects();
        }
    }
    void getObjectsFromBranches()
    {
        if (hasBranches())
        {
            objects.insert(tl->objects.begin(), tl->objects.end());
            objects.insert(tr->objects.begin(), tr->objects.end());
            objects.insert(bl->objects.begin(), bl->objects.end());
            objects.insert(br->objects.begin(), br->objects.end());
        }
    }
    void destroyBranches()
    {
        if (hasBranches())
        {
            delete tl;
            delete tr;
            delete bl;
            delete br;
        }
    }
    bool hasBranches() const
    {
        return (tl && tr && bl && br);
    }
public:
private:
    Aabb2 aabb;
    DynamicQT* tl = nullptr;
    DynamicQT* tr = nullptr;
    DynamicQT* bl = nullptr;
    DynamicQT* br = nullptr;
    std::map<size_t, Object*> objects;
};

注意:更新尚未实施

确切的错误是:

  

错误C2440:'=':无法转换为'DynamicQT&lt; 10,10,true,1&gt; *' 至   “DynamicQT&LT; 10,10,真,0&GT; *'

当我搜索修复时,我不得不删除“深度+ 1”或只删除“+ 1”并编译好但显然不应该发生。

感谢任何帮助(也许代码有任何问题)。

1 个答案:

答案 0 :(得分:1)

DynamicQT的模板参数是实例化类型的一部分。因此,DynamicQT<10,10,true,0>DynamicQT<10,10,true,1>是不相关的类型,它们的指针不能隐式转换为彼此。似乎如果depth为0,则子项应该具有深度1,依此类推,因此您应该声明子指针具有适当的类型:

private:
Aabb2 aabb;
typedef DynamicQT<maxObjects, maxDepth, canDelete, depth+1> ChildDynamicQT;
ChildDynamicQT* tl = nullptr;
ChildDynamicQT* tr = nullptr;
ChildDynamicQT* bl = nullptr;
ChildDynamicQT* br = nullptr;