C++模板:编码错误或编译器错误?

Rod*_*ddy 1 c++ templates stl c++builder

我正在尝试使用模板来获取std:项目列表,其中每个项目都有一个指向包含它的列表的指针,但我一直在点击编译器消息.

这是一个非常精简的代码版本.

template <class E> class Item  
{
    public:
        E* owner; // pointer to list that owns us.
};

template <class E> class BaseList: public std::list<E>
{
protected:
    typedef std::list<E> inherited;
public:

    void push_back(const E &e)
    {
        E tmp(e);
        tmp.owner = this;  // This line gives the error.
        inherited::push_back(tmp);
    }
};

class MyList;

class MyItem : public Item<MyList>
{
};

class MyList : public BaseList<MyItem>
{
};

void foo()  // test code to instantiate template
{
    MyList l;
    MyItem m;
    l.push_back(m);
}
Run Code Online (Sandbox Code Playgroud)

但是,我的编译器barfs在行: -

        tmp.owner = this;  
Run Code Online (Sandbox Code Playgroud)

错误是:

[BCC32 Error] Unit7.cpp(30): E2034 Cannot convert 'BaseList<MyItem> * const' to 'MyList *'
Run Code Online (Sandbox Code Playgroud)

这就像"这个"不知何故变成了常量,但我看不出原因.编译器是Codegear C++ Builder 2009.

我承认我不是百分之百地使用模板,所以我不确定这是我的问题还是编译器.没有模板使用的相同代码编译得很好,但显然这不是我想要的,因为我有几个想要以这种方式工作的项目/列表类.

此外,是否有更好的技术可以避免在每个项目中拥有所有"所有者"指针?

编辑:我认为我将示例剥离得太过分了:"MyList"实际上引入了新方法,"MyItem"必须通过"所有者"指针访问.

摘要:感谢您的所有意见和解答.正如公认的答案所说,问题只是指向BaseList与MyList之间的类型不兼容之一.

提出的关于STL容器和替代设计的问题也很有帮助,但我使用的解决方案基本上与下面的Luc Touraille相同.

Dav*_*nde 8

在第30行,"this"是指向a BaseList<MyIteM>,而不是MyList 的指针.您可以用派生的类替换类,但不能用其他方式替换.

您可以将typedef MyList设置为a BaseList<MyItem>,如下所示:

typedef BaseList<MyItem> MyList
Run Code Online (Sandbox Code Playgroud)

或者让MyItem来源Item<BaseList<MyItem> >.

从类型派生时,可以创建不同的类型.当您键入def时,您将为该类型创建别名.所以当你输入typedef时,编译器会接受这个.