从切换到以参数包作为const参考的令人困惑的错误

时间:2019-04-22 18:46:42

标签: c++

我有这段代码几乎可以按预期工作,基本上我想要一个函数来创建实体而不向其添加任何组件,而一个函数可以创建实体并向其添加组件。所有功能都在一个类EntityManager中。

不带任何组件:

Entity newEntity()
{
    Entity newEntity{ entityCounter };
    entityCount++;
    entityCounter++;

    std::cout << "Called newEntity(void)" << std::endl;

    return newEntity;
}

采用组件:

template <typename... Components>
Entity newEntity(Components... components)
{
    Entity newEntity{ entityCounter };
    entityCount++;
    entityCounter++;

    unpackAndStoreComponentsInManagers(newEntity, std::forward<Components>(components)...);

    std::cout << "Called newEntity(Components)" << std::endl;

    return newEntity;
}

由于可能相关,因此这里也是unpackAndStoreComponentsInManagers

template <typename ComponentType>
void unpackAndStoreComponentsInManagers(const Entity& entity, const ComponentType& component)
{
    newComponent(entity, component);
}

template <typename ComponentType, typename... Rest>
void unpackAndStoreComponentsInManagers(const Entity& entity, const ComponentType& component, const Rest&... rest)
{
    newComponent(entity, component);
    unpackAndStoreComponentsInManagers(entity, rest...);
}

而且,这是主要的

int main()
{
    ComponentA a{ 0.0f, 1.0f, 2.0f };
    ComponentB b{ true };


    EntityManager e;

    e.newEntity();
    e.newEntity(a, b);
}

这可以正常工作并按预期打印:

Called newEntity(void)
Called newEntity(Components)

现在是问题所在,我想在newEntity中使用components参数,而是将它们作为const引用。切换出带有此功能的组件的newEntity

template <typename... Components>
Entity newEntity(const Components&... components)
{
    Entity newEntity{ entityCounter };
    entityCount++;
    entityCounter++;

    unpackAndStoreComponentsInManagers(newEntity, std::forward<Components>(components)...);

    std::cout << "Called newEntity(Components)" << std::endl;

    return newEntity;
}

我得到了错误:

Error 1:
Error   C2665   'std::forward': none of the 2 overloads could convert all the argument types    

Error 2:
Error   C2672   'EntityManager::unpackAndStoreComponentsInManagers': no matching overloaded function found

Error 3:
Error   C2780   'void EntityManager::unpackAndStoreComponentsInManagers(const Entity &,const ComponentType &,const Rest &...)': expects 3 arguments - 1 provided

Error 4:
Error   C2780   'void EntityManager::unpackAndStoreComponentsInManagers(const Entity &,const ComponentType &)': expects 2 arguments - 1 provided

错误1和2在newEntity中与newEntity(Components)中的std :: forward一致。

错误3和4在带有组件的newEntity的声明行上。

如果我从主机中删除

e.newEntity(a, b);

我没有任何错误,它会按预期打印

Called newEntity(void)

如果我从主机中删除

e.newEntity();

我遇到相同的错误,所以罪魁祸首肯定是添加组件的newEntity,但是我不知道为什么...

编辑:已解决,谢谢!

将newEntity(components)更改为

template <typename... Components>
Entity newEntity(const Components&... components)
{
    Entity newEntity{ entityCounter };
    entityCount++;
    entityCounter++;

    unpackAndStoreComponentsInManagers(newEntity, components...);

    std::cout << "Called newEntity(Components)" << std::endl;

    return newEntity;
}

1 个答案:

答案 0 :(得分:0)

一个很长的问题的简短回答。您只应转发通过forwarding reference收到的邮件,即

 template<class T>
 void foo(T&& t) {
     bar(std::forward<T>(t)); // OK
 }

 template<class T>
 void baz(const T& t) {
     bar(std::forward<T>(t)); // NOT OK
 }