将int转换为通用模板类型

时间:2019-06-14 18:58:46

标签: c++

我在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。为什么?

2 个答案:

答案 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) 

请考虑对键进行相同的更改。