C++;多态性模板&引用;使用类模板需要模板参数“; 我是C++的新手,我想知道如何使用模板来构建多态的特定类型的类的层次结构。我知道如何在Java中使用泛型很容易做到这一点。我确信这是以前被问过的,但是我根本不知道用什么术语来搜索我想要的C++。

C++;多态性模板&引用;使用类模板需要模板参数“; 我是C++的新手,我想知道如何使用模板来构建多态的特定类型的类的层次结构。我知道如何在Java中使用泛型很容易做到这一点。我确信这是以前被问过的,但是我根本不知道用什么术语来搜索我想要的C++。,java,c++,templates,generics,polymorphism,Java,C++,Templates,Generics,Polymorphism,我希望能够使用一个基类,该基类是我使用以下定义为Derived_1和Derived_2的指定类组成的对象组合创建的,每个类都从名为base的类扩展而来。但是,我得到一个编译器错误,说我需要声明类型?我使用什么语法来表示实现中使用的z向量可以由从Base扩展的类的任意组合组成 以下是我到目前为止所掌握的内容,我认为在声明基类和扩展该基类的类时,这一点基本上是正确的: 基本类型 模板 阶级基础{ 公众: 底座(尺寸a、b): m_a(a), m_b(b){ } T getB()常量; 尺寸(m)a

我希望能够使用一个基类,该基类是我使用以下定义为
Derived_1
Derived_2
的指定类组成的对象组合创建的,每个类都从名为
base
的类扩展而来。但是,我得到一个编译器错误,说我需要声明类型?我使用什么语法来表示实现中使用的
z
向量可以由从
Base
扩展的类的任意组合组成

以下是我到目前为止所掌握的内容,我认为在声明基类和扩展该基类的类时,这一点基本上是正确的:

基本类型
模板
阶级基础{
公众:
底座(尺寸a、b):
m_a(a),
m_b(b){
}
T getB()常量;
尺寸(m)a ;;
T m_b;
};
//使用布尔的特定类型的基
类派生的\u 1:公共基{
派生的_1(uint32_t a);//第二个参数未使用,假定为“true”
bool-getB();
};
//使用尺寸的特定类型的底座
类派生的\u 2:公共基{
导出的2(uint32\u t a,大小\u t b);
大小_t getB();
};
基本类型.cpp
Derived_1::Derived_1(uint32_t a):Base(a,true){}//第二个参数未使用,假定为“true”
bool派生的_1::getB(){return m_b;}
派生_2::派生_2(uint32_t a,size_t b):基(a,b){
bool派生的_2::getB(){return m_b;}
impl_types.h
#包括“基本类型.h”
#包括
福班{
公众:
福(
尺寸,
const std::vector&z);//错误:使用类模板“Base”需要模板参数
};
impl_types.cpp
class-Foo{
公众:
福(
尺寸,
const std::vector&z)://错误:使用类模板“Base”需要模板参数
m_y{y},
m_z{z};
};
作为参考,以下是我想做的Java实现:
//Base.java
阶级基础{
国际货币基金组织;
T m_b;
基本(内部a、T和b){
m_a=a;
m_b=b;
}
T getB(){
返回m_b;
}
}
//派生的\u 1.java
类派生的_1扩展了基{
派生_1(int a,Boolean a){
超级(a,b);
}
布尔getB(){
返回m_b;
}
}
//派生的_2.java
类派生的_2扩展了基{
派生_2(整数a,字符串b){
超级(a,b);
}
字符串getB(){
返回m_b;
}
}
//Main.java
公共班机{
公共静态void main(字符串[]args){
List baseList=new ArrayList();
添加(新派生的_1(1,true));
添加(新派生的_2(2,“foo”);
for(基本o:基本列表){
System.out.println(o.getB());
}
}
}

您不能拥有
std::vector
,因为
Base
是模板。您应该有
std::vector
std::vector
或类似的内容
Base
Base
是不同的类型,它们除了使用相同的模板
Base
之外没有其他共同之处

可能你想要的是
std::vector
但是 很难从代码中分辨出来。
std::variant
用于使变量具有不同类型的值(可能没有共同点)


您不能将派生类的对象放入基类的向量中,所以当您希望这些对象按值位于同一向量中时,应该使用
std::vector
。动态多态对象必须具有完全相同的基类,即使这样,您也需要通过引用基类而不是值将它们放入容器中。

如果您创建一个非模板化的空基类,一个从它继承的模板,然后进行专门化,您可以将基指针存储在向量或任何其他结构中。
如果要使用存储的对象,必须显式地将它们转换回实际类型(如果我没有说错的话,这也必须用Java完成)。

错误:使用类模板
Base
需要模板参数

您得到错误是因为
Base
不是一个类型,而只是一个模板。不要混淆C++和TEMPALTES和java泛型,它们是非常不同的概念。不能有模板向量,因为模板只是模板。您需要实例化它们以获得类型。例如,您可以有一个
std::vector

代码中的另一个问题是
Base
应该有一个虚拟析构函数。否则,您将面临内存泄漏的危险。方法必须声明为
virtual
,以启用动态调度

话虽如此

您真正想做的事情:

我只想保持一个不同类的对象向量 从公共基类[…]继承

你不需要模板。这将非常简单:

#include <iostream>
#include <vector>
#include <memory>
#include <utility>
struct base { 
    virtual void some_method(){ std::cout << "base\n";}
    virtual ~base(){}
};
struct foo : base {
    virtual void some_method() override { std::cout << "foo\n";}
};
struct bar : base {
    virtual void some_method() override { std::cout << "bar\n";}
};


int main() {
    std::vector<std::shared_ptr<base>> v;
    v.emplace_back(new foo());
    v.emplace_back(new bar());

    for (auto& e : v) e->some_method();
    return 0;
}
然后
example\u-derived::foo
覆盖
example\u-base::foo
!多亏了
override
,编译器将通过沿

prog.cc:20:24: error: 'foo' marked 'override' but does not override any member functions
        virtual double foo() override { return 1.4; }
                       ^
根据您实际想要实现的目标(为什么您需要使用不同的返回类型来“共享一个公共方法”)有不同的解决方法。我给你指一条路

#include <iostream>
#include <vector>
#include <memory>
#include <utility>

struct return_type_base { 
    virtual void print() {}
    virtual ~return_type_base() {}
};

struct bool_return_type : return_type_base {
    bool value = true;
    virtual void print() { std::cout << value << "\n"; }
};
struct int_return_type : return_type_base {
    int value = 3;
    virtual void print() { std::cout << value << "\n"; }
};

using return_type_ptr = std::shared_ptr<return_type_base>;

struct base { 
    virtual return_type_ptr some_method() = 0;
    virtual ~base(){}
};
struct foo : base {
    virtual return_type_ptr some_method() override { 
        return return_type_ptr(new bool_return_type());
    }
};
struct bar : base {
    virtual std::shared_ptr<return_type_base> some_method() override { 
        return return_type_ptr(new int_return_type());
    }
};


int main() {
    std::vector<std::shared_ptr<base>> v;
    v.emplace_back(new foo());
    v.emplace_back(new bar());

    for (auto& e : v) e->some_method()->print();
    return 0;
}
#包括
#包括
#包括
#包括
结构返回\类型\基{
虚拟空打印(){}
虚~return_type_base(){}
};
struct bool\u return\u type:return\u type\u base{
布尔值=真;
java中的虚拟void print(){std::cout这项工作
#include <iostream>
#include <vector>
#include <memory>
#include <utility>

struct return_type_base { 
    virtual void print() {}
    virtual ~return_type_base() {}
};

struct bool_return_type : return_type_base {
    bool value = true;
    virtual void print() { std::cout << value << "\n"; }
};
struct int_return_type : return_type_base {
    int value = 3;
    virtual void print() { std::cout << value << "\n"; }
};

using return_type_ptr = std::shared_ptr<return_type_base>;

struct base { 
    virtual return_type_ptr some_method() = 0;
    virtual ~base(){}
};
struct foo : base {
    virtual return_type_ptr some_method() override { 
        return return_type_ptr(new bool_return_type());
    }
};
struct bar : base {
    virtual std::shared_ptr<return_type_base> some_method() override { 
        return return_type_ptr(new int_return_type());
    }
};


int main() {
    std::vector<std::shared_ptr<base>> v;
    v.emplace_back(new foo());
    v.emplace_back(new bar());

    for (auto& e : v) e->some_method()->print();
    return 0;
}
template<typename T>
auto value() -> T { return T{}; }

int main() {
    return value<int>() + value<short>();
}
template<> //   v---- T has been replaced!
auto value() -> int { return int{}; }

template<> // Another instantiation
auto value() -> short { return short{}; }
struct Interface {
    // TODO: put useful function there
};

template<typename T>
struct Base : Interface {
    virtual auto getB() const -> T;
};

struct Impl1 : Base<bool> {
    auto getB() const -> T override;
};
Base b = ...;

// pseudocode
if (typeid(b->getB()) == bool)
{
    bool b = dynamic_cast<bool>(b->getB());
}
else if (typeid(b->getB()) == std::size_t)
{
    std::size_t b = dynamic_cast<std::size_t>(b->getB());
}
using VBase = std::variant<Base<bool>, Base<std::size_t>, ...>