是否可以在编译时通过constexpr函数分配数组值?

问题描述 投票:0回答:1

我对模板和编译时函数还很陌生,我目前正在尝试编写一个基本的实体组件系统(ECS),该系统将允许我在容器中存储泛型类型(组件)。我希望功能能够在编译时和运行时设置容器。在我的应用程序中有一些实例,我可以肯定哪些组件对于某个实体将始终存在,因此我希望能够在编译时进行设置并保留插槽。在某些情况下,需要在运行时动态删除/添加组件。

template <typename T, size_t N>
struct ComponentArray {
public:
    template<typename... Args>
    constexpr const T& AddComponent(const uint64_t entity, Args &&... args) const
    {
        //T component{ std::forward<Args>(args)... }; //i want to be able to do something like this..
        //m_components[0] = component; //create the component and give it a slot, but this is const
        return m_components[0];
    }

    std::array<T, N>    m_components = {};
    std::array<T, N>    m_entityIds = {};
    uint32_t            m_used = 0;
};

template <uint64_t entityId, typename Component, typename ... Args>
constexpr const Component& AddComponentCT(Args&&... args)
{
    constexpr uint64_t componentHash = GetHashForString(ComponentTypeInfo<Component>::m_name, ComponentTypeInfo<Component>::m_nameLength);
    constexpr uint64_t storageHash = ComponentStorageMapping<componentHash>::m_hash;
    static_assert(storageHash == componentHash);

    constexpr const auto& componentStorage = ComponentStorageMapping<componentHash>::m_componentStorage;

    constexpr const Component& rComponent = componentStorage.AddComponent(entityId /*std::forward<Args>(args)...*/);

    return rComponent;
}


constexpr const TransformComponent transform = AddComponentCT<ENTITY_ID, TransformComponent>(5.0f, 5.0f, 5.0f);

这似乎可行,当我将鼠标悬停在transform上时,我可以看到返回的内容,但显然是不正确的值,因为我无法使用const函数中的参数构造类型。enter image description here

我也曾尝试从变量中删除一些const,但随后它抱怨说东西不是const或无法求值。

我正在使用提供的参数创建Component类型,然后在m_components中找到一个空闲插槽来存储它。这样的事情在编译时可能吗?如果有人对我如何实现我想要的东西或改进解决方案有任何建议,将不胜感激。这里没有包含一些宏代码,这些宏代码会生成类似ComponentStorageMappingComponentTypeInfom_componentStorage]的类。


下面是注释中要求的更简化/通用的版本

struct A
{
    float x, y, z;
};

struct B
{
    int i, j, k;
};

template <typename T, size_t N>
struct C {
public:
    template<typename... Args>
    constexpr const T& AddToArray(Args &&... args) const
    {
        //T element{ std::forward<Args>(args)... }; //i want to be able to do something like this..
        //m_array[0] = element; //create the component and give it a slot, but this is const
        return m_array[0];
    }

    std::array<T, N>    m_array = {};
};


template <typename T, typename ... Args>
constexpr const T& AddElement(Args&&... args)
{
    constexpr const T& element = C<T, 50>::AddToArray(/*std::forward<Args>(args)...*/);

    return element;
}


constexpr const A& someArrayElement = AddElement<A>(5.0f, 5.0f, 5.0f); //this would point to C<A,50>::m_array[0], fully constructed
constexpr const A& someArrayElement2 = AddElement<A>(10.0f, 10.0f, 10.0f); //this would point to C<A,50>::m_array[1], fully constructed

constexpr const B& someArrayElement3 = AddElement<B>(1, 1, 1); //this would point to C<B,50>::m_array[0], fully constructed
constexpr const B& someArrayElement4 = AddElement<B>(2, 2, 2); //this would point to C<B,50>::m_array[1], fully constructed

为了记录,我在此之前创建了另一篇文章(https://gamedev.stackexchange.com/questions/176301/how-can-i-create-a-templated-function-to-add-components-to-their-necessary-conta),以了解我将如何处理这种情况,并且没有收到很多建议,因此我只是尝试自己做,这是我遇到的问题。还有另一个框架可以某种方式实现我正在尝试做的事情,但是我不太了解他们在做什么,因为它们都是模板。到该框架的链接在另一篇文章中。

我对模板和编译时函数还很陌生,我目前正在尝试编写一个基本的实体组件系统(ECS),该系统将允许我在容器中存储泛型类型(组件)。 ...

c++ constexpr compile-time
1个回答
0
投票

我认为您想要的是不可能的。

© www.soinside.com 2019 - 2024. All rights reserved.