java - 是否有等同于 Java <?在 C++ 中扩展 ClassName>?

标签 java c++ templates inheritance

我正在看这个https://docs.oracle.com/javase/tutorial/java/generics/subtyping.htmlhttps://docs.oracle.com/javase/tutorial/java/generics/inheritance.html并问自己如何用 C++ 实现它。

我有这个小例子来说明:

#include <iostream>

class Animal
{
public:
    virtual std::string type() const = 0;
    virtual ~Animal() {}
};

class Dog : public Animal
{
public:
    virtual std::string type() const {
        return "I am a dog";
    }
};

class Cat : public Animal
{
public:
    virtual std::string type() const {
        return "I am a cat";
    }
};

template <typename T>
class AnimalFarm
{
};

void farmTest(const AnimalFarm<Animal *> &farm)
{        
    std::cout << "test farm";
}


int main(int argc, char *argv[])
{          
    AnimalFarm<Dog *> dogFarm;
    AnimalFarm<Animal *> animalFarm;

    farmTest(animalFarm); // OK
    farmTest(dogFarm); // NOK compiler error as class AnimalFarm<Dog *> does not inherits from class AnimalFarm<Animal *>

    return 0;
}

我明白为什么它在 C++ 中不起作用。在 Java 中,解决方案是使用以下构造:

List<? extends Integer> intList = new ArrayList<>();
List<? extends Number>  numList = intList;  // OK. List<? extends Integer> is a subtype of List<? extends Number>

(假设 Integer 是示例链接中指出的 Number 的子类)。

使用:

template <typename U>
void farmTest(const AnimalFarm<U *> &farm);

可能是解决方案,但有没有更好的方法在 C++ 中做到这一点,同时又不丢失 Cat 或 Dog 从 Animal 继承的事实(因为 IntegerNumber 的子类型)?

谢谢。

最佳答案

如果您的最终目标是在 AnimalFarm<Dog *> 之间形成关系和 AnimalFarm<Animal *> , 那么一些具有类型特征的模板特化就可以做到这一点。

template <typename T, typename = void>
class AnimalFarm // Primary template
{
};

template<typename T>
class AnimalFarm<T*,
  std::enable_if_t<
     !std::is_same<T, Animal>::value &&
      std::is_base_of<Animal, T>::value
  >
> // Specialization only instantiated when both conditions hold
  // Otherwise SFINAE
  : public AnimalFarm<Animal*>
{
};

AnimalFarm<Animal*>成为AnimalFarm<Dog*>的公共(public)基地,函数参数引用将绑定(bind)到它。尽管您应该注意到相应的层次结构是扁平的,无论 Animal 有多深一个去。

你可以看看 live .

关于java - 是否有等同于 Java <?在 C++ 中扩展 ClassName>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47979349/

相关文章:

java - 使用端口 1099 的 IntelliJ Idea IDE

c++ - GetMessage/PeekMessage - 删除消息队列中的所有消息

templates - 多路平等测试失败

c++ - C++ 中是否有任何方法允许不同数据类型的不同执行路径?

java - 如何在java中存储一个非常大的整数

java - 获取 Spring MVC 中 JSON 表单绑定(bind)错误的详细信息

java - 如何计算有符号随机整数的绝对值

c++ - dll错误flycapture

c++ - std::enable_if,模板特化和继承

c++ - 检查数字类型是否是另一个的子集