链接列表可能包含不同的元素?

时间:2011-04-30 13:01:04

标签: c++

Hya,

Lemme解释我的观点。

template<typename T>
class node{
  T data;
  template<typename X>
  node<X>* right; // can point to any node<typename> i know its wrong
}

所以我可以做类似的事情:

node<int> a;
a.data = 23;
node<float> b;
b.data =43.6;
a.right= b;
std::cout<< a.data <<a.right->data;

另一个例子:

template <class Type>
struct vnode {
  Type data;
  vnode<Type> * vnodenext;
  // vrow what_to_put_here // **i don't want to use void ptrs neither want to cast back manually**
}

在main函数中,如果我定义类型vnode的{​​{1}}结构和string类型的另一个vnode,那么我应该用{{1}替换什么指针def在int结构定义中,它可以指向vrow类型的vnode或其他类型的vnode? e.g。

int

3 个答案:

答案 0 :(得分:2)

通常,如果没有某种运行时支持,在C ++中是不可能的。但您可以将变量类型用于节点的值,例如,请参阅http://www.boost.org/doc/libs/1_46_1/doc/html/variant.html

答案 1 :(得分:2)

实际上不可能做你想做的事情,因为在使用模板时你必须知道编译时涉及的类型。相反,遍历以前构建的链接列表需要您在运行时发现列表中的类型。

为了说明,请考虑一下:

struct node_base {
    virtual ~node_base() {}
}

template<typename T>
struct node : public node_base {
    T data;
    node_base* right;
}

现在您当然可以拥有node_base*的列表,这些节点可以包含您想要的任何类型的数据。构建列表不是问题,因为在您添加节点时,data的静态类型是已知的,您可以创建node<TData>

现在的问题是如何获取数据。假设有一个函数在给定指向该节点的指针的情况下返回节点内的数据。函数返回类型应该是什么?显然(除非您事先知道所有数据类型共享一个共同的基础),没有可以返回的单一类型。这让你:

  1. 返回void*
  2. 编写一个接收数据类型作为参数的模板化函数
  3. 然而,#2在实践中是不可行的(虽然它在理论上有效)。您不能将数据类型写为模板参数,因为这需要您在编译时知道它,这会破坏多数据类型列表的目的。

    因此,唯一的解决方案是返回一个指针类型(node_base*void*到数据本身),然后使用某种机制将该指针强制转换为有用的类型。

答案 2 :(得分:1)

您应该从共同的祖先派生您的vnode模板,即

struct vnode_base {
    virtual ~vnode_base() {}
};

template <class Type> 
struct vnode : vnode_base {
   // ...
};

并将vnode_base*类型用于节点中的下一个元素指针。由于将基类转换为祖先是隐式的,因此以下赋值可以正常:a.right= &b;

要检查节点是否具有特定类型,请使用C ++的RTTI。没有办法避免这种情况 - 你需要某种运行时类型检查。

vnode<float>* pf = dynamic_cast<vnode<float>* >(a.right);
if (pf) {
    // here we go
}