将运行时研究更改为编译时 [英] Change runtime research for a compile time one

查看:68
本文介绍了将运行时研究更改为编译时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试出于学习目的在C ++中实现通用ECS库.我在想很多方法来实现事情,但是我总是遇到问题.因此,如果您可以帮助我解决这个问题:

假设我有constexpr hana::tuplehana::type_c组件,例如:

Let say I have a constexpr hana::tuple of hana::type_c Components, something like :

struct C1 {};
struct C2 {};
struct C3 {};

constexpr auto components = hana::to_tuple(hana::tuple_t<C1, C2, C3>);

现在我有一个组件存储类型,在这里这不是问题,所以我们将其称为存储(每个组件的类型不同):

And now I have a component storage type, which is not a problem here, so let's call it Storage (the type differ for each component):

struct Storage {};

我想用其Storage类型链接每个组件或每个组件组.因此,简单的方法是执行类似的操作:

I want to link each component or each component group, with their Storage type. So the easy way is to do something like that:

constexpr auto component_storage = hana::make_tuple(
hana::make_pair(hana::to_tuple(hana::tuple_t<C1, C2>), type_c<Storage>),
hana::make_pair(hana::to_tuple(hana::tuple_t<C3>), type_c<Storage>)
);

但是现在的问题是运行时.如果我初始化该元组但使用真正的Storage且不再使用type_c<Storage>,则必须遍历该元组以查找所需的Storage.所有这些在运行时不? 这真的很糟糕,我的上一个版本具有类似Component::getStorage()的内容,并且它是免费的(但更具限制性).

But the problem now is runtime. If I initialize that tuple but with the real Storage and no longer type_c<Storage>, I'll have to loop through the tuple to find the Storage that I need. All of this at runtime no? And this is really bad, my last version had something like Component::getStorage() and it was free (but more restrictive).

所以问题是:我该如何管理一些getStorage<Component>()函数,该函数在运行时不会花费任何费用?没什么,我的意思是只返回存储的引用.

So the question is : how can I manage to have some getStorage<Component>() function which will cost nothing at runtime? Well by nothing I mean just return the reference of the Storage.

到目前为止,我唯一认为的方法很简单(听起来很不错).

The only way I have think so far is quite simple (sounds like a good point).

伪代码

struct LinkedStorage {

  hana::tuple<...>            storages;
  hana::tuple<hana::pair...>  index;
};

至少不要这样:

constexpr auto components = hana::to_tuple(hana::tuple_t<C1, C2, C3>);
constexpr auto storage = hana::to_tuple(hana::tuple_t<Storage, Storage>);
constexpr auto index = hana::make_tuple(
hana::make_pair(hana::to_tuple(hana::tuple_t<C1>, 0),
hana::make_pair(hana::to_tuple(hana::tuple_t<C2, C3>, 1)
);

就像我应该能够在编译时找到索引,并在运行时访问正确的元素一样.但是我是元编程的新手,所以我想有人可以做得更好.

Like that I should be able to found the index at compile time and just access the right element at runtime. But I'm new at metaprogramming, so I guess someone could make something far better.

推荐答案

首先,无需使用to_tuple(tuple_t<...>);您可以只使用tuple_t<...>.现在,我认为您实际想要做的(因为您似乎需要运行时存储,这很有意义)是:

First of all, no need to use to_tuple(tuple_t<...>); you can just use tuple_t<...>. Now, I think what you actually want to do (since you seem to need runtime storage, which makes sense) is:

// "map" of a set of types to a storage of some type
using StorageMap = hana::tuple<
  hana::pair<hana::tuple<hana::type<C1>, hana::type<C2>>, StorageA>,
  hana::pair<hana::tuple<hana::type<C3>>, StorageB>
>;
// Actual object that contains the runtime storage (and the free mapping between types)
StorageMap map;

现在,您可以像这样实现getStorage<Component>()函数:

Now, you can implement your getStorage<Component>() function like this:

template <typename Component>
decltype(auto) getStorage() {
  auto found = index_if(map, [](auto const& pair) {
    return hana::contains(hana::first(pair), hana::type<Component>{});
  });
  return hana::second(hana::at(map, found));
}

其中,index_if是此答案中给出的函数的琐碎变体,它将代替任意谓词特定元素的.当我有空闲时间时,此功能将添加到Hana中(请参阅相关票证)

where index_if is a trivial variant of the function presented in this answer that would work on an arbitrary predicate instead of a specific element. This functionality will be added to Hana when I get some free time (see related ticket).

这篇关于将运行时研究更改为编译时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆