Lỗi C2280 khi compile code trên Visual Studio 2017

Cho em nhờ mọi người một chút là lỗi của em giải quyết ntn ạ?
‘ComponentArray::ComponentArray(void)’: attempting to reference a deleted function

Em gặp lỗi khi chạy dòng lệnh sau: componentManager.RegisterComponent();

ComponentArray.h

#pragma once

#include "Types.h"
#include <cassert>
#include <unordered_map>
#include <array>

class IComponentArray {
public:
    virtual ~IComponentArray() = default;
    virtual void EntityDestroyed(Entity entity) = 0;
};

template<typename T>
class ComponentArray : public IComponentArray {
private:
    std::array<T, MAX_ENTITIES> mComponentArray;
    std::unordered_map<Entity, size_t> mEntityToIndexMap;
    std::unordered_map<size_t, Entity> mIndexToEntityMap;
    size_t mSize;

public:
    void InsertData(Entity entity, T component) {
          assert(mEntityToIndexMap.find(entity) == mEntityToIndexMap.end() &&
                "Component added to the same entity.");

          size_t newIndex = mSize;
          mEntityToIndexMap[entity] = newIndex;
          mIndexToEntityMap[newIndex] = entity;
          mComponentArray[newIndex] = component;

          mSize++;
    }

    void RemoveData(Entity entity) {
          assert(mEntityToIndexMap.find(entity) != mEntityToIndexMap.end() && 
                "Removing non-existent component.");

          size_t indexOfRemovedEntity = mEntityToIndexMap[entity];
          size_t indexOfLastElement = mSize - 1;
          mComponentArray[indexOfRemovedEntity] = mComponentArray[indexOfLastElement];

          Entity entityOfLastElement = mIndexToEntityMap[indexOfLastElement];
          mEntityToIndexMap[entityOfLastElement] = indexOfRemovedEntity;
          mIndexToEntityMap[indexOfRemovedEntity] = entityOfLastElement;

          mEntityToIndexMap.erase(entity);
          mIndexToEntityMap.erase(indexOfLastElement);

          mSize--;
    }

    T& GetData(Entity entity) {
          assert(mEntityToIndexMap.find(entity) != mEntityToIndexMap.end() &&
                "Retrieving non-existent component.");

          return mComponentArray[mEntityToIndexMap[entity]];
    }

    void EntityDestroyed(Entity entity) override {
          if (mEntityToIndexMap.find(entity) != mEntityToIndexMap.end()) {
                RemoveData(entity);
          }
    }
};

ComponentManager.h

#pragma once

#include "Types.h"
#include "ComponentArray.h"
#include <cassert>
#include <unordered_map>

class ComponentManager {
private:
    std::unordered_map<const char*, ComponentType> mComponentTypes;
    std::unordered_map<const char*, std::shared_ptr<IComponentArray>> mComponentArrays;
    ComponentType mNextComponentType;

    template<typename T>
    std::shared_ptr<ComponentArray<T>> GetComponentArray() {
          const char* typeName = typeid(T).name();
          assert(mComponentTypes.find(typeName) != mComponentTypes.end() &&
                "Component not registered before use.");

          return std::static_pointer_cast<ComponentArray<T>>(mComponentArrays[typeName]);
    }

public:
    template<typename T>
    void RegisterComponent() {
          const char* typeName = typeid(T).name();
          assert(mComponentTypes.find(typeName) == mComponentTypes.end() &&
                "Registering component type more than once.");

          mComponentTypes.insert({ typeName, mNextComponentType });
          mComponentArrays.insert({ typeName, std::make_shared<ComponentArray<T>>() });

          mNextComponentType++;
    }

    template<typename T>
    ComponentType GetComponentType() {
          const char* typeName = typeid(T).name();
          assert(mComponentTypes.find(typeName) != mComponentTypes.end() &&
                "Component not registered before use.");

          return mComponentTypes[typeName];
    }

    template<typename T>
    void AddComponent(Entity entity, T component) {
          GetComponentArray<T>()->InsertData(entity, component);
    }

    template<typename T>
    void RemoveComponent(Entity entity) {
          GetComponentArray<T>()->RemoveData(entity);
    }

    template<typename T>
    T& GetComponent(Entity entity) {
          return GetComponentArray<T>()->GetData(entity);
    }

    void EntityDestroyed(Entity entity) {
          for (auto const& pair : mComponentArrays) {
                auto const& component = pair.second;
                component->EntityDestroyed(entity);
          }
    }
};

Transform.h

struct Transform {
     Vec2 position;
};

Nếu chỉ gọi componentManager.RegisterComponent(); không thôi thi compiler không thể suy ra kiểu của T nên nó không thể tạo instance method từ template được.

Bạn cần chỉ rõ cho compiler biết T là gì.
VD: componentManager.RegisterComponent<void>(); hoặc componentManager.RegisterComponent<int>();.

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?