C++ 模板类并根据迭代调用不同的构造函数

C++ 模板类并根据迭代调用不同的构造函数,c++,class,templates,amazon-ecs,entities,C++,Class,Templates,Amazon Ecs,Entities,我正在学习ECS,现在我正在尝试为我的项目实现组件 所以,让你们了解一下,我有一个水族馆,里面有很多组件(比如海藻和鱼)。两者都有年龄,但只有鱼类才有种族 我有一个类用于一般的_组件(年龄和其他内容)和一个类用于鱼类特定的组件(种族、性别等) 我创建了一个模板组件类,其创建方法如下所示: template<typename ConcreteComponent> // ConcreteComponent is attached to the class ConcreteComponen

我正在学习ECS,现在我正在尝试为我的项目实现组件

所以,让你们了解一下,我有一个水族馆,里面有很多组件(比如海藻和鱼)。两者都有年龄,但只有鱼类才有种族

我有一个类用于一般的_组件(年龄和其他内容)和一个类用于鱼类特定的组件(种族、性别等)

我创建了一个模板组件类,其创建方法如下所示:

template<typename ConcreteComponent> // ConcreteComponent is attached to the class
ConcreteComponent& Components<ConcreteComponent>::create( entity e ) {
    m_components.push_back( ConcreteComponent(e) );
    return m_components.back();
}

我在C中看到过类似的东西,但建议不要碰它,因为它已经过时,不再使用。

这里的解决方案是使用参数包和
std::forward
将传入实际构造函数的任何参数传递给它。下面是一个完整但简化的示例(无数据结构,每种类型一个参数):

#include <iostream>

class Fish {
public:
    Fish(std::string const &name) {
        std::cout << "Making a fish named " << name << '\n';
    }
};

class Seaweed {
public:
    Seaweed(int length) {
        std::cout << "Making a seaweed that's " << length << " feet long\n";
    }
};

template <typename ConcreteComponent, typename ...ARGS>
ConcreteComponent create(ARGS && ...args) {
    return ConcreteComponent(std::forward<ARGS>(args)...);
}

int main() {
    create<Fish>("Bob");
    create<Seaweed>(42);
    return 0;
}
关于
std::forward
,值得一读,但我们在这里基本上做的是获取
create
中的所有内容,并将其传递给类型的构造函数,同时还保留类型的属性(例如,它是否是临时的)。因此,您可以传递任何内容,只要有一个有效的构造函数来传递内容


我的代码是用C++11、14和17用g++-7.3.0测试的。

您最好使用面向对象编程中使用的类继承


构建基类及其继承类,这样生成的继承类的对象就可以由它们的不同属性动态生成。

您可以使用C++11或更高版本吗?使用参数包和
std::forward
看起来很简单。我可以,我的编译器现在设置为c++17,我将看看这些东西!我对编程非常陌生,所以我仍然不知道大多数事情。如果向量的类型为
std::vector
,您是否知道会发生类型擦除?我不确定您所说的类型擦除是什么意思,但如果无法按组件的性质对其进行排序,然后,我的程序中的所有内容都基于每个实体的唯一ID,所以这不是问题(我不知道“类型擦除”,我的想法基于此链接:)@Tommy XavierRobillard啊,对不起,正确的术语应该是。正如您在回答问题的注释中所阐明的,对于不同的对象,您有不同的向量,因此不会发生。在练习中,他们在评论中说,尝试ECS风格是个好主意(这也是我正在学习的),因为我们必须实现所有类型的方法(例如eat(eater,target)根据食肉动物是食草动物还是食肉动物,会有不同的输入,所以很难做到这一点way@Tommy-XavierRobillard我错过了什么吗?到目前为止,你似乎还没有使用。我的链接正确吗?你只尝试将不同的元素放入
std::vector
中。但由于这些元素的类型不同,Yang的应用程序roach是一个不错的选择。请注意,向量需要管理指向公共基类的指针,否则会发生类型擦除!@Aconcagua我不想扩展自己:我像github.com/TommyXR/maryanic_old这样开始练习,但后来发现所有名称空间和我决定从头开始的所有内容都很混乱用I个类代替,这里我是**,我不确定你的意思。每种类型我有一个不同的向量。我的向量不是heterogenous@Tommy-XavierRobillard好吧,那就忘了我的评论吧——用不同的向量,对象切片(从一开始就应该是正确的术语)不会发生的,我假设你想把所有对象放在同一个向量中。但是,如果你发现这是一个有用的特性,那么回到这个答案上来……我会更深入地研究这个问题,我不是那种做我不懂的事情的人,这看起来真的很有用。非常感谢!!
template<typename A>
void myClass<A>::create( list_of_parameters) {
A(list_of_parameters) /*calls the constructor of the template class A */
}
#include <iostream>

class Fish {
public:
    Fish(std::string const &name) {
        std::cout << "Making a fish named " << name << '\n';
    }
};

class Seaweed {
public:
    Seaweed(int length) {
        std::cout << "Making a seaweed that's " << length << " feet long\n";
    }
};

template <typename ConcreteComponent, typename ...ARGS>
ConcreteComponent create(ARGS && ...args) {
    return ConcreteComponent(std::forward<ARGS>(args)...);
}

int main() {
    create<Fish>("Bob");
    create<Seaweed>(42);
    return 0;
}
$ ./forwarding
Making a fish named Bob
Making a seaweed that's 42 feet long