- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我最近一直在试验参数包,因为它们似乎满足了我开发中的一个相当大的需求。但是,我一直遇到一个问题,参数包似乎是一个可行的解决方案,但我无法弄清楚这个特定问题。当前的问题是如何获取参数包中的每个类型,从该类型的静态字段中检索第 n 个元素,并在元组中返回该元素(连同其他元素)。如果措辞有点不清楚,我当前的用例如下:
/* 警告:可能是不必要的细节 */
我的程序的架构是 Entity-Component System 的架构.本质上,有多个系统定义了程序不同区域的逻辑。这些系统作用于由多个组件组成的实体(其中包含特定的数据,例如 DescriptionComponent)。每个系统将验证给定实体是否具有所有必需的组件,然后执行特定于系统的逻辑。
为此,我创建了一个组件基类,从中派生出特定的组件。每个派生组件都包含一个静态 vector ,它充当该类型所有组件的管理器。每个组件都有一个引用其所属实体的 entityId 字段,静态 vector 按此 ID 排序。
目前,在给定的系统中,我能够通过查看系统所需的组件找到适用的实体,然后找到包含相同 entityId 的组件集并对这些组件执行逻辑。但是,此时我正在执行逻辑以手动遍历组件的静态 vector ,因为每个系统在组件类型方面都有不同的要求。
一个简单的例子,以防上面的内容不清楚:
假设 DisplaySystem 需要一个 PictureComponent 和一个 PositionComponent。现在说管理这些类型的静态字段如下:
PictureComponent::elements = [(picture: "somePic.jpg", id: 1), (picture: "otherPic.jpg", id: 2)]
PositionComponent::elements = [(pos: (1,2), id: 2), (pos: (4,5), id: 3)]
目前,每个组件都有自己的迭代器。从零开始,我们用最低的 entityId 提高组件索引(因为 vector 是根据这个键排序的)。在上面的示例中,我们将尝试索引 (0,0),看到 id 1 小于 id 2,因此增加第一个索引。然后我们会尝试 (1,0),看到两个组件都有 entityId 2,并将它们作为对传递给系统以执行逻辑。然后我们会增加两个索引,尝试 (2,1),并超出 PictureComponent vector 的范围,然后完成。
/* 结束不必要的细节 */
对于这个问题,我设想的解决方案是一个单一的模板化参数包类,它接收所需的组件类型并输出 entityId 全部匹配的组件的元组。伪代码如下
template <typename... RequiredComponentTypes>
class ComponentIterator {
/* standard input iterator functionality*/
...
array componentIndices // same size as our param pack, one index per type
tuple<RequiredComponentTypes...> getNextSetOfComponents() {
while every component's entity id is not equal:
find the currently indexed component with the lowest entity id;
increment the current index of that component type;
out of the while, once we have a set of components with the same entity id:
return a tuple of the indexed components for each type. **//this is the part I have no idea how to do**
}
}
如代码中所述,将其值从索引检索到类型的静态字段的元组返回的过程是我不确定的部分。对于任意数量的模板参数,手动执行都是微不足道的(如果我有一组命名参数化类型,那么制作元组就像使用适当的值调用 make_tuple 一样简单。)但是,在处理参数包时,我'我不确定如何解决这个问题。
如果您能提供任何帮助,我们将不胜感激,如果您需要任何说明或更多详细信息,请随时告诉我。谢谢!
最佳答案
你可以这样做:
template <typename... Ts>
class ComponentIterator {
static constexpr std::size_t size = sizeof...(Ts);
public:
ComponentIterator() : indices(), finished(false) { adjust(); }
std::tuple<Ts&...> get()
{
return get(std::index_sequence_for<Ts...>());
}
ComponentIterator& operator ++()
{
for (auto& e : indices) {
++e;
}
adjust();
return *this;
}
bool is_finished() const { return finished; }
private:
void adjust()
{
adjust(std::index_sequence_for<Ts...>());
}
template <std::size_t...Is>
std::tuple<Ts&...> get(std::index_sequence<Is...>)
{
return std::tie(Ts::elements[indices[Is]]...);
}
template <std::size_t...Is>
void adjust(std::index_sequence<Is...>) {
bool is_ended[size] = {indices[Is] == Ts::elements.size()...};
if (std::any_of(std::begin(is_ended), std::end(is_ended),
[](bool b) { return b; })) {
finished = true;
return;
}
int min_value = std::min({Ts::elements[indices[Is]].id...}) - 1;
for (;;)
{
++min_value;
bool increases[size] = {increase_until<Ts>(indices[Is], min_value)...};
if (std::any_of(std::begin(increases), std::end(increases),
[](bool b) { return !b; })) {
finished = true;
return;
}
const int ids[size] = {Ts::elements[indices[Is]].id...};
if (std::all_of(std::begin(ids), std::end(ids),
[min_value](int id) { return id == min_value;})) {
return;
}
}
}
template <typename T>
bool increase_until(std::size_t& index, int min_value)
{
for (; index != T::elements.size(); ++index) {
if (min_value <= T::elements[index].id) {
return true;
}
}
return false;
}
private:
std::array<std::size_t, size> indices;
bool finished;
};
关于c++ - 取决于静态参数包字段的返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27773271/
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 5 年前。 Improve
在 C# 静态方法中是否有一种方法可以引用定义该方法的类型? 在实例方法中,您可以通过以下方式确定类型: public void Foo() { Type type = this.GetTyp
WPF:静态、动态资源以及资源词典 静态资源与动态资源 我们常常会使用样式或者控件模板放在Window.Resources中,比如这样: 静态资源与动态资源使用如下: <Window
任何人都知道如何在共享/静态函数中动态加载控件?该函数本身位于 mustinherit/abstract 类中。 (这是 VB 中的 ASP.NET 项目)我想做这样的事情: VB: Publ
在我看来,静态/强类型编程语言最宝贵的一点是它有助于重构:如果/当您更改任何 API,那么编译器会告诉您该更改破坏了什么。 我可以想象用运行时/弱类型语言编写代码......但我无法想象没有编译器的帮
正如我的名字所暗示的,我是一名 .NET 开发人员,但我对 Java 的兴趣越来越大,并且我有兴趣学习更多其他语言,因为这有助于我学习更多关于编程的知识。 无论如何,我的问题是:不带参数/不使用状态的
我在java中使用WireMock来 stub POST请求。该请求返回一个存储在我本地的 json 正文文件。 stub 看起来像这样: wireMockServer.stubFor(get(url
Python 是否有类构造函数的机制,即每当首次引用类时(而不是创建该对象的实例时)调用的函数?我知道其他一些语言中也存在这种情况,但我还没有在 Python 中遇到过。 基本上,我想初始化该函数中的
Python 是否有类构造函数的机制,即每当首次引用类时(而不是创建该对象的实例时)调用的函数?我知道其他一些语言中也存在这种情况,但我还没有在 Python 中遇到过。 基本上,我想初始化该函数中的
这个问题已经有答案了: What is the difference between dynamic and static polymorphism in Java? (14 个回答) 已关闭 4 年
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Static initializer in Java 我想知道这个静态的东西(抱歉,这是我第一次遇到这个)对一个类有
如果c++应用程序是按以下方式组织的 //file1.cpp static Y sgObj = X::getInitObject(0); //declared in file scope //fil
我有一个抽象类(AvergedDataRecord),我需要进一步抽象(DataRecord),这样我就可以将它扩展到原始类和一个新的具体类(SummedDataRecord),并且我在获取某些方法时
我正在尝试制作一个字符串枚举。这是我到目前为止所得到的, private class TypedEnum : IEnumerable { public IEnumerator GetEnume
我选修了一门名为“安全代码”的类(class),在下一个作业中,我们应该对一些 C 文件和 JavaEE Web 项目进行静态/动态分析。 我检查了“源监视器”并在 C 文件上运行它,但是(除非我不知
我有两个类,一个是登录类,一个是用户类。在 loggedIn 类中,我想显示我在用户登录时所做的共享首选项。 loginPrefs = getSharedPreferences("loginprefe
我在同一个 Activity 中有两个静态 fragment ,在“fragmentA”中我有一个自定义列表,当一个项目被点击时必须在“fragmentB”中出现一个细节,细节只在我改变屏幕方向时出现
在 Java 中是未修改方法变量,缺少final,每次都重新初始化限定符 静态方法 实例方法 如果 1. 或 2.(或两者)的答案是 final 限定符允许 Java 执行优化并存储方法变量只有一次?
我有两个类相互交互。第一个是中心的,如下: public class Datenbank { double winkelPanel = 0; double groessePanel = 0; doub
我有一个 mysql 数据库,它连接基于 Web 的 php 应用程序和 FoxPro 应用程序(是的,foxpro)。在之前的“开发人员”被解雇后开始处理这个问题。 无论如何,我熟悉 AES_Enc
我是一名优秀的程序员,十分优秀!