2013-07-28 3 views
-1

템플릿 기반 데이터 관리 기능을 사용하기 위해 공유 포인터를 가져 오는 데 문제가 있습니다. I와 같은, 다양한 목적을위한로드 데이터를 포함하는 간단한 구조체 가지고C++ : 템플릿 함수로 shared_ptr이 제대로 실행되지 않습니다.

이러한 데이터 구조체의 인스턴스가 구성된다
struct loadedShipData_t { 
    enum VARIABLES { 
     // snip for readability: lots of variable names for identification 
    }; 

    std::string textureKey; 
    std::array<int, 20> data; 
}; 

struct loadedStarfieldData_t { 
    enum VARIABLES { 
     // snip for readability: lots of variable names for identification 
    }; 

    std::array<int, 8> data; 
}; 

는 포인터가 간은 각각의 순서화지도 삽입된다 (데이터 유형 당 하나) , 필요할 때마다 액세스 할 수 있도록

std::unordered_map<std::string, std::shared_ptr<loadedShipData_t>> shipData; 
std::unordered_map<std::string, std::shared_ptr<loadedStarfieldData_t>> starfieldData; 

... 등등.

구현하는 데 문제가있는 템플릿 함수는 getData라는 하나의 클래스이며, 지정된 키의 정렬되지 않은 맵에 저장된 데이터 구조체에 대한 포인터를 반환합니다.

template <typename DATA> 
    std::shared_ptr<DATA> getData(DATA_TYPES dataType, const std::string& key) { 
     switch (dataType) { 
      case STARFIELD_DATA: 
       return starfieldData.at(key); 
      case SHIP_DATA: 
       return shipData.at(key); 
      // snip for readability: all the other data types 
      default: 
       throw UNDEFINED_DATA_TYPE(); 
       break; 
     }; 
    } 

이 기능은 다음과 같은 호출됩니다

std::shared_ptr<loadedStarfieldData_t> loadedData = data.getData<loadedStarfieldData_t>(STARFIELD_DATA, key); 
std::shared_ptr<loadedShipData_t> loadedShipData = data.getData<loadedShipData_t>(SHIP_DATA, "Debug"); 

그리고 오류 메시지 : 내가 이상보고와 코드를 엉망으로 한

<file_path> error C2664: 'std::shared_ptr<_Ty>::shared_ptr(std::nullptr_t)' : cannot convert parameter 1 from 'std::shared_ptr<_Ty>' to 'std::nullptr_t' 
      with 
      [ 
       _Ty=loadedShipData_t 
      ] 
      and 
      [ 
       _Ty=loadedStarfieldData_t 
      ] 
      nullptr can only be converted to pointer or handle types 
      <file_path> : see reference to function template instantiation 'std::shared_ptr<_Ty> DataManager::getData<loadedShipData_t>(DATA_TYPES,const std::string &)' being compiled 
      with 
      [ 
       _Ty=loadedShipData_t 
      ] 
<file_path> error C2664: 'std::shared_ptr<_Ty>::shared_ptr(std::nullptr_t)' : cannot convert parameter 1 from 'std::shared_ptr<_Ty>' to 'std::nullptr_t' 
      with 
      [ 
       _Ty=loadedStarfieldData_t 
      ] 
      and 
      [ 
       _Ty=loadedShipData_t 
      ] 
      // snip for readability: other data types 
      nullptr can only be converted to pointer or handle types 
      <file_path> : see reference to function template instantiation 'std::shared_ptr<_Ty> DataManager::getData<loadedStarfieldData_t>(DATA_TYPES,const std::string &)' being compiled 
      with 
      [ 
       _Ty=loadedStarfieldData_t 
      ] 
      // snip for readability: other data types 

수많은 시간을 한없이 때문에, 다른 사람들과 비슷한 문제가 발생했는지 알 수있을 것이라고 생각했습니다. 여기에 몇 가지 유사한 질문이 있지만 잘못되고있는 부분을 파악할 수 없었기 때문에 내 자신의 문제에 대한 세부 정보를 게시하고이 부분의 C++ 전문가가 나를 가리킬 수 있는지 확인했습니다. 바른 길.

시간 내 주셔서 감사합니다.

P. 그게 도움이된다면 Visual Studio 2012로 컴파일 중입니다.

+1

'getStarFieldData'와'getShipData' 함수를 별도로 사용하지 않는 이유는 무엇입니까? –

+0

많은 데이터 유형이 있기 때문에 나는 단지 게으르 길 원한다고 생각합니다. 아, 그럼! 제안 주셔서 감사 드리며, 아마도 그 일을 끝낼 것입니다. – SamuelMS

답변

4

shared_ptr<loadedShipData_t>을 보이는 모양으로 shared_ptr<loadedStarfieldData_t>으로 변환하려고합니다. 짐작할 수 있듯이, 아마도 호환되지 않는 포인터 유형 일 수 있으며, loadedStarfieldData_t*을 반환한다고 선언 된 함수에서 loadedShipData_t*을 반환하려는 것과 같은 이유로 작동하지 않습니다.

이에 라인을 확장하려면 :
std::shared_ptr<loadedStarfieldData_t> loadedData = data.getData<loadedStarfieldData_t> STARFIELD_DATA, key); 

이에 기본적으로 템플릿을집니다 :

std::shared_ptr<loadedStarfieldData_t> getData(DATA_TYPES dataType, const std::string& key) { 
    switch (dataType) { 
     case STARFIELD_DATA: 
      return starfieldData.at(key); 
     case SHIP_DATA: 
      return shipData.at(key); // <-- type mismatch here 
     // snip for readability: all the other data types 
     default: 
      throw UNDEFINED_DATA_TYPE(); 
      break; 
    }; 
} 
+0

별 호출이 우주선 호출에 완전히 연결되지 않았으므로 그렇게해서는 안됩니다. 아니면 내가 보지 않은 코드에 특정 내용을 언급하고 있습니까?loadShipData_t 구조체와 loadedStarfieldData_t 구조체에 대한 예제 호출을 원래 게시물에 추가하여 명확성을 높였습니다. – SamuelMS

+2

정확합니다. * 귀사는 return 문 중 하나만 실행된다는 것을 알지만 컴파일러는 나머지를 컴파일합니다. –

+0

동일한 함수에서 두 개의 다른 유형을 반환 할 수 없습니다. 함수가 템플릿 인 경우에도 마찬가지입니다. 당신은 그것을하기 위해 둘 다 변환 할 수있는 일종의 일반적인 유형을 가져야합니다. – Joel

2

함수 템플릿 마술 런타임에 유형을 변경할 수있는 기능이 아닙니다. 그것은 전혀 기능이 아닙니다. 정기적 인 비 매직 기능을 만드는 방법입니다. 고정 된 타입 세트로 원하는 것을 수행하는 함수를 작성할 수 없다면, 그것을하는 마법 템플릿을 작성할 수 없습니다.

런타임 인수에 따라 유형 A 또는 유형 B를 반환하는 함수를 작성하려고합니다. 이러한 함수는 C++에는 존재하지 않으며 템플릿을 사용하여 만들 수 없습니다.

+0

그래, 내가하려고했던 일이 효과가 없을 것이라는 점이 상당하다. 왜 내가 처음에 가능했는지 확신 할 수 없다. 도와 주셔서 감사합니다. – SamuelMS

관련 문제