初始化自定义地图类对象会导致错误C2783

时间:2015-10-04 18:11:28

标签: c++ dictionary tree binary-tree

我最近将自己的自定义地图类实现为我的C-runtime独立项目的std :: map替换。我知道它可能不如std :: map那么高效,但它可以达到目的。

这是包含所需结构对和节点的类的方式(我删除了大部分与我的问题无关的函数):

template< class T, class U >
class Map;

template< class T, class U >
struct Pair
{
    T first;
    U second;
};

template< class T, class U >
class Node
{
    friend class Map<T, U>;
public:
    T first;
    U second;

protected:
    Node<T, U>* pParent;
    Node<T, U>* pLeft;
    Node<T, U>* pRight;

public:
    Node(T SetFirst,
        U SetSecond,
        Node<T, U>* pSetParent)
    {
        this->first = SetFirst;
        this->second = SetSecond;
        this->pParent = pSetParent;
    }
};

template< class T, class U >
class Map
{
private:
    Node<T, U>* pRoot,
        *pCurrentNode;

private:
    template< typename N >
    static N Insert(const T& SetFirst,
        const U& SetSecond,
        Node<T, U>*& Leaf)
    {
        if (!Leaf)
        {
            Leaf = new Node<T, U>(SetFirst,
                SetSecond,
                nullptr);

            Leaf->pLeft = nullptr;
            Leaf->pRight = nullptr;

            return Leaf;
        }
        else if (SetFirst < Leaf->first)
        {
            if (Leaf->pLeft != nullptr)
                return Insert<N>(SetFirst,
                    SetSecond,
                    Leaf->pLeft);
            else
            {
                Leaf->pLeft = new Node<T, U>(SetFirst,
                    SetSecond,
                    Leaf);

                Leaf->pLeft->pLeft = nullptr;
                Leaf->pLeft->pRight = nullptr;

                return Leaf->pLeft;
            }
        }
        else
        {
            if (Leaf->pRight != nullptr)
                return Insert<N>(SetFirst,
                    SetSecond,
                    Leaf->pRight);
            else
            {
                Leaf->pRight = new Node<T, U>(SetFirst,
                    SetSecond,
                    Leaf);

                Leaf->pRight->pLeft = nullptr;
                Leaf->pRight->pRight = nullptr;

                return Leaf->pRight;
            }
        }
    }

public:
    Map()
    {
        this->pRoot = nullptr;
        this->pCurrentNode = nullptr;
    }

    Map(const Map& SetMap)
    {
        this->pRoot = nullptr;
        this->pCurrentNode = nullptr;

        this->operator=(SetMap);
    }

    Map& operator=(Map& SetMap)
    {
        this->Clear();

        if (!SetMap.Empty())
        {
            for (auto it = SetMap.Begin(); it != nullptr; it = SetMap.Next())
                this->Insert(it->first,
                    it->second,
                    this->pRoot);
        }

        return *this;
    }
};

因为我的项目是独立于C运行时的,所以我必须负责初始化静态变量,就像我自己在我的项目中使用的一些Map对象一样,所以我这样做就像例如 &#34; Keys = Map();&#34;。 在编译该代码时,它给了我一个错误C2783基本上说&#34;模板参数为&#34; N&#34;无法推断出#34; (我将这些错误翻译成英文,因为我的Visual Studio设置为德语)。 过了一会儿,我看到我没有为operator =中的插入调用指定任何N,所以我开始考虑为什么我甚至需要N并决定将它从函数中删除它以及在类中调用Insert的所有地方。 完成后,Insert函数看起来像这样:

static Node<T, U>* Insert(const T& SetFirst,
        const U& SetSecond,
        Node<T, U>* Leaf)
    {
        if (!Leaf)
        {
            Leaf = new Node<T, U>(SetFirst,
                SetSecond,
                nullptr);

            Leaf->pLeft = nullptr;
            Leaf->pRight = nullptr;

            return Leaf;
        }
        else if (SetFirst < Leaf->first)
        {
            if (Leaf->pLeft != nullptr)
                return Insert(SetFirst,
                    SetSecond,
                    Leaf->pLeft);
            else
            {
                Leaf->pLeft = new Node<T, U>(SetFirst,
                    SetSecond,
                    Leaf);

                Leaf->pLeft->pLeft = nullptr;
                Leaf->pLeft->pRight = nullptr;

                return Leaf->pLeft;
            }
        }
        else
        {
            if (Leaf->pRight != nullptr)
                return Insert(SetFirst,
                    SetSecond,
                    Leaf->pRight);
            else
            {
                Leaf->pRight = new Node<T, U>(SetFirst,
                    SetSecond,
                    Leaf);

                Leaf->pRight->pLeft = nullptr;
                Leaf->pRight->pRight = nullptr;

                return Leaf->pRight;
            }
        }
    }

然而,在编译之后,我确实不再得到编译器错误,而是“#34;警告C4239非标准扩展&#34;参数&#34;转换自&#34; Map&amp;&#34;&#34;多次出现在输出窗口中,点击它时会将我重定向到代码行,例如&#34; TestMap = Map();&#34; (这个显然只是我添加到我的项目中的代码,用于测试与此问题相关的事情)并且在运行它时我的程序崩溃了。 我班上究竟出了什么问题,我真的需要那个&#34; N&#34;插入中的模板还是可以以其他方式解决?

0 个答案:

没有答案