C++ 无法转换';克莱斯特<;int>;::节点*';至';克莱斯特<;char>;::节点*';委派

C++ 无法转换';克莱斯特<;int>;::节点*';至';克莱斯特<;char>;::节点*';委派,c++,templates,casting,circular-list,C++,Templates,Casting,Circular List,在这里,我制作了一个循环链表(模板类clist;),其中包含一个成员函数,concat(),用于将一个列表连接到另一个列表的末尾。问题在于这个函数。现在,当我使用相同的模板参数连接两个clist(假设两者都是clist)时,函数工作正常,但只要我尝试连接两个clist(clist c1和clist c2),我就需要对函数concat进行一些转换,由于我对模板不太了解,我想不出该怎么做 所以问题就出在下面程序的最后第二行。我有clist c1,它的成员函数concat正在被调用,还有clist c

在这里,我制作了一个
循环链表(模板类clist;)
,其中包含一个成员函数,
concat()
,用于将一个列表连接到另一个列表的末尾。问题在于这个函数。现在,当我使用相同的模板参数连接两个
clist
(假设两者都是
clist
)时,函数工作正常,但只要我尝试连接两个
clist
clist c1
clist c2
),我就需要对函数
concat
进行一些转换,由于我对模板不太了解,我想不出该怎么做

所以问题就出在下面程序的最后第二行。我有
clist c1
,它的成员函数
concat
正在被调用,还有
clist c2
在c1的末尾被连接

template <class t>
class clist
{
    struct node
    {
    t data;
    node* next;
    node (const t& x=0, node* nxt=0): data(x), next(nxt) { }
    };

    typedef node* NPTR;

    public:

    NPTR ptr;

    template <class r>
    void concat ( clist <r> & );

    // other functions like push, pop etc. to form the clist

    clist () : ptr(0) { }
};

template <class t>
template <class r>
void clist<t> :: concat ( clist <r>& c2 )
{
    // ptr is pointer to a certain node in the list through which the list is
    // accessedand is zero initially.

    if ( c2.ptr == 0 ) return;
    if ( ptr == 0 ) ptr = (NPTR) c2.ptr;
    else
    {
    NPTR p = ptr->next;
    ptr->next = (NPTR) c2.ptr->next;
    c2.ptr->next = ( ??? ) p ;
    ptr = (NPTR)c2.ptr;
}
模板
类clist
{
结构节点
{
t数据;
节点*下一步;
节点(const t&x=0,node*nxt=0):数据(x),下一个(nxt){}
};
typedef节点*NPTR;
公众:
NPTR-ptr;
模板
空心混凝土(clist&);
//其他功能,如推送、弹出等,以形成clist
clist():ptr(0){}
};
模板
模板
void clist::concat(clist&c2)
{
//ptr是指向列表中的某个节点的指针,列表通过该节点进行访问
//accessedand最初为零。
如果(c2.ptr==0)返回;
如果(ptr==0)ptr=(NPTR)c2.ptr;
其他的
{
NPTR p=ptr->next;
ptr->next=(NPTR)c2.ptr->next;
c2.ptr->next=(?)p;
ptr=(NPTR)c2.ptr;
}
无论我尝试什么,它仍然显示错误
无法将赋值中的'clist::node*'转换为'clist::node*'。


有人能告诉我什么是正确的强制转换方式吗?

强制转换实际上是为了避免您创建异构列表。您似乎想做的是将两个列表连接起来,一个是int,一个是char。从概念上讲,这似乎是合理的,但int节点和char节点的结构太不同了


唯一有意义的方法是将第二个列表复制到int的clist中,然后将其连接起来。

模板参数既不是协变的,也不是逆变的;
clist
clist
是完全不同的类型。不能在它们之间进行转换。因为
节点的定义包含在对于模板类型,它也依赖于模板参数,并且相应的
节点
类型也类似地不同


每个列表只能包含一种类型。如果您试图编写一个可以包含任何类型的列表,则需要为模板参数使用变体样式类型。

但是,如果我只需要创建一个异构列表,该怎么办?没有任何方法可以做到这一点吗?是的,您是对的。当我甚至无法访问但是仍然有一种方法可以成功地实现它。协变表达式可能不是最好的。它通常用于讨论继承关系中类型的关系,其中,如果遵循相同的继承方向,则关系是协变的,如果遵循相反的继承方向,则关系是逆变的le:
struct A{};struct B:A{};struct base{virtual A*f();};struct-derived:base{B*f();}
f
的返回类型是协变的:
A
B
之间的关系的变化方向与
base
derived
之间的关系的变化方向相同。然而,模板参数不是协变的……也不是逆变的。无法将
Foo
转换为
f在这个例子中,逆差可能是正确的术语,而
int
is不是“派生”
char
,它是一种更广泛的类型。