C++ 调用接收派生类列表的方法不';t在C+中编译+;

C++ 调用接收派生类列表的方法不';t在C+中编译+;,c++,inheritance,C++,Inheritance,我试图理解为什么不能将派生类类型的列表传递给定义为获取基类类型列表作为参数的函数 #include <iostream> #include <list> using std::list; class foo { }; class bar : foo { }; static void print_all(list<foo*> &L) { } void main() { list<foo*> LF; list<ba

我试图理解为什么不能将派生类类型的列表传递给定义为获取基类类型列表作为参数的函数

#include <iostream>
#include <list>
using std::list;
class foo {

};

class bar : foo {

};
static void print_all(list<foo*> &L) {

}
void main() {
    list<foo*> LF;
    list<bar*> LB;
    print_all(LB); // error
    print_all(LF); // works fine
}
#包括
#包括
使用std::list;
福班{
};
酒吧类别:富{
};
静态无效打印(列表和列表){
}
void main(){
列出LF;
列表LB;
打印全部(磅);//错误
print_all(LF);//工作正常
}

提前感谢。

由于是模板,
std::list
std::list
是完全不相关的类型。但是,即使这与模板无关(您可能会尝试通过继承显式地安装这样的关系),也有一个很好的理由可以解释为什么这仍然不起作用(假设这是合法的……):

void f(标准::列表和列表)
{
l、 向后推(新的foo());
}
void g()
{
std::列表l;
f(l);
//现在我包含一个foo对象,它不是bar对象!!!
}
顺便问一下,你有没有注意到C++ STL从来没有把容器传递给函数?您可以尝试相同的方法:

template <typename Iterator>
void print_all(Iterator begin, Iterator end)
{
    for(; begin != end; std::advance(begin))
    {
        // print *begin
    }
}

print_all(lf.begin(), lf.end());
print_all(lb.begin(), lb.end());
模板
void print_all(迭代器开始、迭代器结束)
{
for(;begin!=end;std::advance(begin))
{
//打印*开始
}
}
全部打印(左开始(),左结束());
全部打印(磅开始(),磅结束());

如果您的目标只是从
foo
bar
打印信息,那么您不需要两个列表,您可以有一个列表,该列表的参数是基类指针(
foo
的指针)和一个
print
函数,该函数是
虚拟的

那么您的代码将是:

class foo {
    public:
    virtual void print() { cout<< "printing foo\n"; }
};

class bar :  public foo {
    public:
    void print() { cout<< "printing bar\n"; }
};
static void print_all(list<foo*>& L) {
    for(auto const& i: L)
    {
        i->print();
    }
}
int main() {

    list<foo*> LB;
    foo f;
    bar b;
    LB.push_back(&f);
    LB.push_back(&b);
    print_all(LB);     
}
class-foo{
公众:

virtual void print(){coutBecause
list
list
不相关。它们是独立的类型。而
bar*
可以传递给需要
foo*
的函数(由于继承)一旦你使它变得更复杂,类型将不再兼容。不是你的print_all函数必须处理多态性,而是你的list。
list LB;LB.push_back(new bar())这是一个问题。
list
list
是不相关的类型,但这并不是因为
list
是一个模板。一个
foo*
数组和一个
bar*
数组也是不相关的类型。@Peter Hm,我想说这仍然是真的-但这不是那些类型可以不相关的唯一原因…我的观点是与继承相反:
my傻瓜列表{};MyBarList:publicmy傻瓜列表{}
虽然可以实现类似的类,但很快就会遇到此答案中显示的所有问题……另一种解决方案是使用模板:@Cactus实际上,我也在使用模板……我的变体更像人们从STL中非常熟悉的模式,所以在这种情况下,我更喜欢它。不过,你的变体也很不错,将非常适合不支持迭代器的数据类型…太糟糕了,问题已经解决了,希望您将其作为自己的答案发布。@Aconcagua抱歉,我读得太快了,如果类型是可写的,您的肯定会更好。
class foo {
    public:
    virtual void print() { cout<< "printing foo\n"; }
};

class bar :  public foo {
    public:
    void print() { cout<< "printing bar\n"; }
};
static void print_all(list<foo*>& L) {
    for(auto const& i: L)
    {
        i->print();
    }
}
int main() {

    list<foo*> LB;
    foo f;
    bar b;
    LB.push_back(&f);
    LB.push_back(&b);
    print_all(LB);     
}