gpt4 book ai didi

c++ - 跟踪实例化的模板化类型C++

转载 作者:行者123 更新时间:2023-12-01 14:44:44 25 4
gpt4 key购买 nike

我正在重新设计实体组件系统的实体管理器。由于组件没有重叠的功能,因此我不希望它们具有可以存储的共享库。

所以我想出了这样的东西:

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

class Component1{};
class Component2{};
class Component3{};

class Manager{
public:
template<typename T> static std::vector<std::shared_ptr<T>> component;

template<typename T> static std::shared_ptr<T> getComponent(int nth){
return component<T>[nth];
}

template<typename T> static std::shared_ptr<T> addComponent(int nth){
return component<T>[nth] = shared_ptr<T>(new T());
}

static void addEntity(){
// push back a nullptr for every instantiated component<>
}

static void removeEntity(int nth){
// set the nth index of every component<> to nullptr
}
};

template<typename T>
std::vector<std::shared_ptr<T>> Manager::component = std::vector<std::shared_ptr<T>>();

int main(){
Manager::component<Component1>;
Manager::component<Component2>;
Manager::component<Component3>;

Manager::addEntity();
auto cmp2 = Manager::getComponent<Component2>(0);

Manager::removeEntity(0);

std::cin.get();
return 0;
}

如何遍历两个函数的实例化组件?尝试使用type_info的 vector 存储Component类型,但是我永远无法从它们中获取合适的类型以用作模板参数。

最佳答案

您可以使用get a unique ID for your types的模板元编程技巧开始。
然后,您可以使用具有唯一类型ID的 map ,而不是变量模板 vector 。通过在基本Component类中引入多态性,再加上static_cast(以减少运行时成本),您可以轻松地重新实现以前的addComponent和getComponent方法。由于具有 map 访问权限,因此它们的使用成本会稍高一些,但是最后,您可以通过遍历 map 来实现addEntity和removeEntity,从而实现所需的功能。

这是上述想法的实现:

#include <vector>
#include <map>
#include <memory>
#include <iostream>

typedef void(*unique_id_type)();

template <typename... Arguments>
struct IdGen {
static constexpr inline unique_id_type get_unique_id()
{
return &IdGen::dummy;
}

private:
static void dummy() {};

};

class Component {};
class Component1 : public Component {};
class Component2 : public Component {};
class Component3 : public Component {};

class Manager {
public:
static std::map<unique_id_type, std::vector<std::shared_ptr<Component>>> components;

template<typename T> static std::shared_ptr<T> getComponent(int nth) {
return std::static_pointer_cast<T>(components[IdGen<T>::get_unique_id()][nth]);
}

template<typename T> static std::shared_ptr<T> addComponent(int nth) {
return std::static_pointer_cast<T>(components[IdGen<T>::get_unique_id()][nth] = std::shared_ptr<T>(new T()));
}

static void addEntity() {
for (auto& component : components)
component.second.push_back(nullptr);
}

static void removeEntity(int nth) {
for (auto& component : components)
component.second[nth] = nullptr;
}
};

std::map<unique_id_type, std::vector<std::shared_ptr<Component>>> Manager::components = {
{ IdGen<Component1>::get_unique_id(), {} },
{ IdGen<Component2>::get_unique_id(), {} },
{ IdGen<Component3>::get_unique_id(), {} },
};

int main() {
Manager::addEntity();
auto cmp2 = Manager::getComponent<Component2>(0);

Manager::removeEntity(0);

std::cin.get();
return 0;
}

PS =此代码使用constexpr和列表初始化等C++ 11功能,但是由于您已经在使用C++ 14(即使您没有将问题标记为C++ 14),所以我认为这不是问题。

PS 2 =由于我正在使用static_cast进行向下转换,因此您不应该对组件使用虚拟继承(请阅读 why)。

关于c++ - 跟踪实例化的模板化类型C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40496369/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com