我在TreeWrapper.h
中具有以下功能:
template<typename Key, typename Data, class Compare=std::less<Key>>
class TreeWrapper{
// .............
public:
void addNode(Key &key, Data &data) {
currentAVLTree.addNode(key, data);
}
我想使用以下命令:
currentGroup.addNode(group, group.getTotal());
但是getTotal
返回int
而不返回Data
。是否可以通过某种方式进行转换?我以为Data
是可以获取任何类型的泛型类型。为什么它不起作用?
编辑:
在TreeWrapper.h
中,重要部分:
template<typename Key, typename Data, class Compare=std::less<Key>>
class TreeWrapper {
AVLTree<Key, Data, Compare> currentAVLTree;
public:
void addNode(Key &key, Data &data) {
currentAVLTree.addNode(key, data);
}
};
在AVLTree.h
中:
template<typename Key, typename Data, class Compare=std::less<Key>>
class AVLTree {
Compare keyCompare;
AVLNode<Key, Data> *root;
int length;
public:
bool addNode(Key &key, Data &data) {
// impl
}
};
在GroupWrapper
中:
class GroupWrapper {
private:
TreeWrapper<Group, Group, compareGroup> currentGroup;
public:
void addGroup(Group group) {
currentGroup.addNode(group, group.getTotal());
}
};
但是我得到一个错误:Parameter type mismatch: Expression must be lvalue
上的group.getTotal()
,它建议将Data
更改为int
。为什么?
答案 0 :(得分:2)
我认为
Data
是可获取任何类型的通用类型。
不完全是。确实Data
代表通用类型,但是该视图仅在定义模板时成立。使用模板时,将对其进行实例化。实例化的一部分涉及为通用模板参数提供具体的替换。对于该实例,替换是固定的,不再是通用的。
例如,查看您的TreeWrapper
模板的声明。
template<typename Key, typename Data, class Compare=std::less<Key>>
class TreeWrapper
使用和实例化此模板的一种方法是使用类似如下的行:
TreeWrapper<Group, Group, compareGroup> currentGroup;
有效地,这采用TreeWrapper
模板,并将“ Key
”的每个实例替换为“ Group
”,将“ Data
”的每个实例替换为“ {{1 }}”,以及“ Group
”和“ Compare
”的每个实例。结果是compareGroup
类型的定义。
因此,currentGroup
的签名如下:
addNode
您可以尝试调用void addNode(Group &key, Group &data)
,但是由于currentGroup.addNode(group, group.getTotal())
返回getTotal()
(不能转换为int
),因此签名不匹配。
(只是)此调用的一种解决方案是建议更改Group &
的具体替换方式。如果要使用
Data
那么TreeWrapper<Group, int, compareGroup> currentGroup;
的签名就是
addNode
和对void addNode(Group &key, int &data)
的调用几乎 * 匹配。但是,除非您决定使用currentGroup.addNode(group, group.getTotal())
作为树的数据类型,而又不了解树将容纳的数据类型,否则这可能会弄乱其他事情。
* “几乎”,因为这会将临时对象绑定到非const引用。由于Group
听起来好像没有任何改变其两个参数的业务,因此它们应该是常量引用(或非引用值),这样才能使您的呼叫正常工作。
addNode
这应该在void addNode(const Key &key, const Data &data)
和TreeWrapper
中进行。
答案 1 :(得分:0)
您正在传递非常量引用,这就是为什么它抱怨lvalue的原因,lvalue可以位于赋值的左侧。如果要将函数引用放在左侧,则函数调用需要返回一个引用,而您的返回则只是纯整数。
更改 getTotal 来返回引用可能是一个非常糟糕的主意,因此有两个解决方案。
至少为数据添加const:
bool addNode(Key &key, const Data &data)
或传递一个值:
bool addNode(Key &key, Data data)
请考虑对键进行相同的更改。