模板 类 并根据迭代调用不同的构造函数
Template classes and calling different constructors depending on iteration
我正在学习 ECS,现在正在尝试为我的项目实施组件。
所以为了让您了解情况,我有一个水族馆,里面有很多组件(比如海藻和鱼)。两者都有年龄,但只有鱼有种族。
我有 class general_components(年龄和其他东西)和 class 鱼类特定成分(种族、性别等)。
我用看起来像这样的创建方法制作了一个模板组件 class:
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();
}
我遇到的问题是我希望能够根据我拥有的 class 调用不同的构造函数(而不是这里的实体 e,它对我设置中的每个 class 都是通用的),但同时保持最有效的方式(因此使用模板并且每个 class 都没有复制粘贴)。对于我的问题,这不会是世界末日,但总的来说,如果我再次遇到这个问题,我想做好准备。
有没有办法调用不同参数的创建函数?
例如:
A<fishComponents> myClassIter;
myClassIter.create("name", age, race, sex)
For fishes 会将 "name",age,race,sex
传递给 ConcreteComponent()
构造函数,而不仅仅是 e
(而且我有 fishComponents
的 "name",age,race,sex
构造函数)。
TL;DR: 在模板 class 方法中,是否可以根据参数
template<typename A>
void myClass<A>::create( list_of_parameters) {
A(list_of_parameters) /*calls the constructor of the template class A */
}
我在 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;
}
输出:
$ ./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 进行了测试。
你最好使用面向对象编程中使用的class的继承。
构建基础class及其继承的classes,因此生成的继承classes的对象可以根据其不同的属性动态生成。
我正在学习 ECS,现在正在尝试为我的项目实施组件。
所以为了让您了解情况,我有一个水族馆,里面有很多组件(比如海藻和鱼)。两者都有年龄,但只有鱼有种族。
我有 class general_components(年龄和其他东西)和 class 鱼类特定成分(种族、性别等)。
我用看起来像这样的创建方法制作了一个模板组件 class:
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();
}
我遇到的问题是我希望能够根据我拥有的 class 调用不同的构造函数(而不是这里的实体 e,它对我设置中的每个 class 都是通用的),但同时保持最有效的方式(因此使用模板并且每个 class 都没有复制粘贴)。对于我的问题,这不会是世界末日,但总的来说,如果我再次遇到这个问题,我想做好准备。
有没有办法调用不同参数的创建函数?
例如:
A<fishComponents> myClassIter;
myClassIter.create("name", age, race, sex)
For fishes 会将 "name",age,race,sex
传递给 ConcreteComponent()
构造函数,而不仅仅是 e
(而且我有 fishComponents
的 "name",age,race,sex
构造函数)。
TL;DR: 在模板 class 方法中,是否可以根据参数
template<typename A>
void myClass<A>::create( list_of_parameters) {
A(list_of_parameters) /*calls the constructor of the template class A */
}
我在 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;
}
输出:
$ ./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 进行了测试。
你最好使用面向对象编程中使用的class的继承。
构建基础class及其继承的classes,因此生成的继承classes的对象可以根据其不同的属性动态生成。