c ++模板和多态性没有用户定义的转换

时间:2016-11-23 20:20:02

标签: c++ templates polymorphism

无法理解此转换的方式(以及原因)无效。

我有A类,B类派生自A类,C类派生自B类。

class A {};
class B : public A {};
class C : public B {};

我想创建一个具有两个模板类型名<K, V>的HashTable,其中K是char,V是二叉搜索树模板类(BST<T>)。这些BST的类型名称为ABC

template <typename K, typename V>
class HashTable {
public:
    bool put(K key, V value);   // adds key value pair to table
private:
    V* table;   // table stores values
    int size;   // size of table
};

template <typename T>
class BST {
public:
    bool insert(T item);    // adds item to tree
private:
    struct BSTNode {        // node structure
        R data;             // item data
        BSTNode *left;      // left child pointer
        BSTNode *right;     // right child pointer
    };
    BSTNode *root;          // pointer to root of tree
};

以下代码在哈希表中放置BST<C>时出错,因为它无法从BST<C>转换为BST<A>。但是,主要的最后一行是合法的。

int main() {
    HashTable<char, BST<A>> inventory;
    BST<C> foo;
    inventory.put('C', foo);

    A *bar= new C();
}

我虽然因为多态性,BST<C>是一个BST<A>?如何解决这种类型差异,以便将BST,BST和BST添加到我的hashmap中?

我已经尝试在声明中使用typedef但是没有用。

2 个答案:

答案 0 :(得分:1)

转换不可能发生。 BST<C>无法转换为BST<A>,因为它们是完全不同的,不相关的类。

当模板实例化时,它看起来像这样(粗略地):

template <>
struct BST_C {
    bool insert(C item);    // adds item to tree
    // ...
};

template <>
struct BST_A {
    bool insert(A item);    // adds item to tree
    // ...
};

如您所见,两者之间没有关系。

你能做些什么呢?

好吧,你可以定义一个转换运算符,仅限于基类:

template <typename T>
struct BST {
    bool insert(T item);

    // only enable for base classes ------------v
    template<typename To, std::enable_if_t<std::is_base_of<To, T>>* = nullptr>
    operator BST<To> () const {
        // implement the conversion operator...
    }
};

使用该转化运算符,您的班级BST<C>可分别转换为BST<B>BST<A>

答案 1 :(得分:0)

这是因为即使BA存在is-a关系,BST<A>BST<B>的关系也没有。这两个模板实例或者以任何方式彼此不相关,实际上可能彼此完全不同。