简体   繁体   中英

Dog is Animal but list<Dog> is not list<Animal>. How to use it safely in a generic/polymorphic function?

It is well-known that a Dog is an Animal but List<Dog> is not List<Animal> ( SO question )

Anyway, if we have a function

void f(Animal a1, Animal a2); // Java

void f(Animal * a1, Animal * a2) // C++

We can safely use f() passing in objects of type Dog / Dog*

Now suppose, we want to generalize it as if it has many arguments of type Animal by using a List of them (and not specifically a multiple argument list ... ). The List is not going to be modified by the function, adding a Cat to a List<Dog> for instance.

This:

void fg (List<Animal>); // Java
void fg (List<Animal *>) // C++

is not going to allow a call passing in a List<Dog> / List<Dog*> value.

What is the way to go?

May be in Java

void fg (List<? extends Animal>)

and in C++

template<T>
void fg (List<T>)

Is that ok?
Are there other alternatives?

Thanks.

The list is not going to be modified by the function [...]. What is the way to go?

In Java, declare a parameter of type List<? extends Animal> List<? extends Animal> . This provides a wildcard bounded by Animal type argument to the List generic parameter. You can read that as a list of any unknown type that extends Animal . The fact that it is an unknown type means that the only type that can be used wherever a value of the List 's type parameter T is expected is the null type, whose only value is null .

A List<Dog> is a type that fits that description, so is a List<Cat> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM