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

时间:2018-08-19 05:49:41

标签: c++ class templates amazon-ecs entities

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

因此,根据您的实际情况,我有一个水族馆,里面有很多东西(比如说海藻和鱼)。两者都有年龄,但只有鱼有种族。

我有一个用于一般成分(年龄和其他东西)的类,以及一个与鱼类有关的成分(种族,性别等)的类。

我使用如下所示的create方法制作了一个模板组件类:

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();
}

我遇到的问题是,我希望能够根据我拥有的类来调用不同的构造函数(而不是这里的实体e,它对于我的设置中的每个类都是通用的),但同时保持最有效的方式(因此使用模板,每个课程都没有复制粘贴)。对于我的问题,这不是世界末日,但总的来说,如果我再次遇到这个问题,我想做好准备。

是否可以使用不同的参数调用创建函数?

例如:

A<fishComponents> myClassIter;
myClassIter.create("name", age, race, sex)

对于鱼类来说,会将"name",age,race,sex传递给ConcreteComponent()的构造函数,而不是仅传递给e(而且我有"name",age,race,sex的{​​{1}}构造函数)。

TL; DR:在模板类方法中,是否可以根据参数将不同数量和值的性质传递给所用类的构造函数

fishComponents

我在C语言中看到了类似的内容,但建议不要触摸它,因为它已过时且不再使用。

2 个答案:

答案 0 :(得分:2)

这里的解决方案是使用参数包和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;
}

输出:

$ ./forwarding
Making a fish named Bob
Making a seaweed that's 42 feet long

关于std::forward值得一读,但是我们在这里基本上要做的是将create中包含的所有内容都传递给类型的构造函数,同时还要保留类型的属性(例如,是否是临时的)。因此,只要有有效的构造函数将事物传递给您,就可以传递任何东西

我的代码已经使用C ++ 11、14和17在g ++-7.3.0上进行了测试。

答案 1 :(得分:1)

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

构建基类及其继承的类,以便可以通过其不同的属性动态生成生成的继承类的对象。