C++ 初始化自定义映射类对象会导致错误C2783
我最近实现了自己的自定义映射类,作为我的独立于C运行时的项目的std::map替换。我知道它可能没有std::map那么有效,但它满足了它的目的 这就是包含所需结构对和节点的类的外观(我删除了与问题无关的大多数函数):C++ 初始化自定义映射类对象会导致错误C2783,c++,dictionary,tree,binary-tree,C++,Dictionary,Tree,Binary Tree,我最近实现了自己的自定义映射类,作为我的独立于C运行时的项目的std::map替换。我知道它可能没有std::map那么有效,但它满足了它的目的 这就是包含所需结构对和节点的类的外观(我删除了与问题无关的大多数函数): 模板 类图; 模板 结构对 { T第一; U秒; }; 模板 类节点 { 好友类地图; 公众: T第一; U秒; 受保护的: 节点*pParent; 节点*pLeft; 节点*pRight; 公众: 节点(T)首先, U秒, 节点*pSetParent) { 此->第一个=设置第
模板
类图;
模板
结构对
{
T第一;
U秒;
};
模板
类节点
{
好友类地图;
公众:
T第一;
U秒;
受保护的:
节点*pParent;
节点*pLeft;
节点*pRight;
公众:
节点(T)首先,
U秒,
节点*pSetParent)
{
此->第一个=设置第一个;
此->秒=设置秒;
此->pParent=pSetParent;
}
};
模板
类图
{
私人:
节点*pRoot,
*pCurrentNode;
私人:
模板
静态N插入(常数T和设置优先,
常数U和设置秒,
节点*&叶)
{
如果(!叶)
{
叶=新节点(SetFirst,
第二,
nullptr);
叶->pLeft=nullptr;
叶->pRight=nullptr;
回叶;
}
else if(SetFirstfirst)
{
如果(叶->pLeft!=nullptr)
返回插入(先设置,
第二,
叶->褶皱);
其他的
{
Leaf->pLeft=新节点(SetFirst,
第二,
叶);
叶->折叠->折叠=nullptr;
叶->褶皱->pRight=nullptr;
返回叶->折叠;
}
}
其他的
{
如果(叶->优先级!=nullptr)
返回插入(先设置,
第二,
叶->顶;
其他的
{
Leaf->pRight=新节点(SetFirst,
第二,
叶);
叶->pRight->pLeft=nullptr;
叶->优先级->优先级=空PTR;
返回叶->右侧;
}
}
}
公众:
地图()
{
此->pRoot=nullptr;
此->pCurrentNode=nullptr;
}
地图(常量地图和集合地图)
{
此->pRoot=nullptr;
此->pCurrentNode=nullptr;
此->运算符=(设置映射);
}
映射和运算符=(映射和设置映射)
{
这个->清除();
如果(!SetMap.Empty())
{
for(auto it=SetMap.Begin();it!=nullptr;it=SetMap.Next())
这个->插入(它->首先,
这是第二次,
这个->pRoot);
}
归还*这个;
}
};
因为我的项目是独立于C运行时的,所以我必须负责初始化静态变量,比如我自己在项目中使用的一些映射对象,所以我就这样做了
“Keys=Map();”。
在编译代码时,它给了我一个错误C2783,基本上是说“N”的模板参数无法推断”(我自己将这些错误翻译成英语,因为我的Visual Studio设置为德语)。
过了一段时间,我发现我没有为operator=中的insert调用指定任何N,因此我开始思考为什么我甚至需要该N,并决定将其从函数和类中调用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;
}
}
}
static Node*插入(const T&SetFirst,
常数U和设置秒,
节点*叶)
{
如果(!叶)
{
叶=新节点(SetFirst,
第二,
nullptr);
叶->pLeft=nullptr;
叶->pRight=nullptr;
回叶;
}
else if(SetFirstfirst)
{
如果(叶->pLeft!=nullptr)
返回插入(先设置,
第二,
叶->褶皱);
其他的
{
Leaf->pLeft=新节点(SetFirst,
第二,
叶);
叶->折叠->折叠=nullptr;
叶->褶皱->pRight=nullptr;
返回叶->折叠;
}
}
其他的
{
如果(叶->优先级!=nullptr)
返回插入(先设置,
第二,
叶->顶;
其他的
{
Leaf->pRight=新节点(SetFirst,
第二,
叶);
叶->pRight->pLeft=nullptr;
叶->优先级->优先级=空PTR;
返回叶->右侧;
}
}
}
然而,编译后,我不再得到编译器错误,而是在输出窗口中多次出现了一个从“Map&”转换而来的“Warning C4239 Non-standard extension”参数,单击该参数可将我重定向到代码行,如“TestMap=Map();”(这显然只是我添加到项目中用于测试与此问题相关的东西的代码)运行时,我的程序崩溃了。
我的类到底出了什么问题?我真的需要Insert中的“N”模板,还是可以通过其他方式解决它?它被标记为“C”哈哈,我把标签搞乱了,因为这是我的第一个问题,它抱怨我添加了很多标签tags@Paranaix没错,我没有注意到,但问题是操作符=使用Begin和Next的方式不可能将其更改为常量引用,因为通过SetMap进行迭代的方式实际上会更改pCSetMap的urrentNode成员。@ccman32好吧,这就是constness的作用。如果必须修改某些内容,它不是const。请找出解决方法,或者不要将其声明为const。(提示:使用当前节点mem)
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;
}
}
}