2016-08-31 4 views
-4

지도에 여러 유형의 객체를 저장하고 싶습니다.이 솔루션을 생각해 냈습니다. 각 객체의 유형을 알아야하므로 boost :: any을 사용할 수 없습니다. 이 작업을 수행 할 수있는 더 좋은 방법이 있습니까? 아니면이 솔루션을 사용할 수 있습니까?지도에 여러 유형 저장

enum eType 
{ 
    TYPE_STRING, 
    TYPE_NUMBER, 
}; 

class CType 
{ 
public: 
    int GetType() { return m_Type; } 

protected: 
    int m_Type; 
}; 

template <typename T> 
class CData : public CType 
{ 
public: 
    CData(const T & rData, int iType) 
    { 
     m_Type = iType; 
     m_Data = rData; 
    } 

    T & GetData() { return m_Data; } 

private: 
    T m_Data; 
}; 

std::map<unsigned long, CType *> map_Data; 

void main() 
{ 
    // Create a new data with TYPE_NUMBER 
    CData<short> data(32767, TYPE_NUMBER); 

    // Add it to the map 
    map_Data[0] = &data; 

    // Get the type 
    switch (map_Data[0]->GetType()) 
    { 
     case TYPE_NUMBER: 
     { 
      // Cast the first element to CData 
      CData<short> * pField = (CData<short> *)map_Data[0]; 

      // Print the data 
      printf("Data: %d\n", pField->GetData()); 
     } 
     break; 

     case TYPE_STRING: 
     { 
      // Cast the first element to CData 
      CData<std::string> * pField = (CData<std::string> *)map_Data[0]; 

      // Print the data 
      printf("Data: %s\n", pField->GetData().c_str()); 
     } 
     break; 
    } 
} 
+1

실행을 시도 했습니까? 또한'void main'이 존재하지 않습니다 – TemplateRex

+0

확실히 시도했는데, 그것은 Visual Studio에서 작동합니다. – JOkle

+0

의견을 묻습니다. 당신이 그것을 돌리면, 컴파일러는 그것을 받아 들였다. 그게 충분하니? – CAB

답변

1

boost::anyboost::any_cast 사용.

any가 int인지 확인하십시오.

bool is_int(const boost::any & operand) 
{ 
    return operand.type() == typeid(int); 
} 

당신이 getType, 기본 및 사용하기 쉬운 솔루션은 태그 사용과 같은 기능을 가진 클래스를 오염하지 않으려면 어떤이 const char *

bool is_char_ptr(const boost::any & operand) 
{ 
    try 
    { 
     any_cast<const char *>(operand); 
     return true; 
    } 
    catch(const boost::bad_any_cast &) 
    { 
     return false; 
    } 
} 
0

인 경우 체크를 볼 수 다음 예와 같은 조합입니다.

0

당신의 질문은 흥미 롭습니다. 왜 그렇게 downvoted인지 이해하지 못합니다. 불행히도 당신이하려고하는 것은 C++에서 불가능합니다 (Java 또는 C#에서 가능할 지 궁금합니다)

다시 질문의 핵심이되는 링크를 넣습니다. 이 구현의 아웃

creating-an-interface-for-an-abstract-class-template-in-c++

은 흥미 롭다.

#include <iostream> 
#include <string> 
#include <sstream> 
#include <List> 

using namespace std; 

struct CType 
{ 
    int GetType() { return m_Type; } 
    string GetStringVal() { return m_string_val; } 
    enum eType {  TYPE_STRING, 
        TYPE_NUMBER }; 
protected: 
    int m_Type; 
    string m_string_val; 
}; 

template <typename T> 
class CData : public CType 
{ 
public: 
    CData(const T & rData):m_Data(rData) 
    { 
     stringstream strs; 
     m_Type = GetType(); 
     //Mingw bug 
     //m_string_val = std::to_string(m_Data); //c++11 
     strs << m_Data; 
     m_string_val = strs.str(); 
    } 

    T & GetData() { return m_Data; } 

private: 
    T m_Data; 
    CType::eType GetType(); 
}; 

template<> CType::eType CData<int>::GetType() { return TYPE_NUMBER; }; 
template<> CType::eType CData<string>::GetType() { return TYPE_STRING; }; 
//More specialization here 

int main() 
{ 
    cout << "Hello world!" << endl; 

    CData<int> cd_int(5); 
    CData<string> cd_str("SO contribution"); 

    list<CType> my_list = { cd_int, cd_str }; 

    for (auto & elem : my_list) 
     cout << elem.GetStringVal() << endl; 

    return 0; 
} 

결과는 자연적 :

세상 안녕하세요 난 당신이 불쾌한 스위치 케이스없이 일부 라인을 마련 할 수있는 생각하는 난 그냥 여기에 몇 가지 재를 넣어!

5

"와 SO 기여

----- ADD-ON 2,016 -9-05 다른 가능성 함수를 저장하는 -----

(람다 이 "캡처) 결과 자체 대신 결과를 반환합니다. m_Data 필드가 변경 될 때 업데이트를 수행하지 않습니다.

#include <iostream> 
#include <string> 
#include <sstream> 
#include <List> 
#include <functional> 

using namespace std; 

struct CType 
{ 
    int GetType() { return m_Type; } 
    string GetStringVal() { return m_string_func(); } 
    enum eType {  TYPE_STRING, 
        TYPE_NUMBER }; 
protected: 
    int m_Type; 
    function<string()> m_string_func ; 
}; 

template <typename T> 
class CData : public CType 
{ 
    public: 
    CData(const T & rData):m_Data(rData) 
    { 
     m_Type = GetType(); 
     m_string_func = [this](){ //MinGW bug,otherwise to_string() 
            stringstream strs; 
            strs << m_Data; 
            return strs.str();}; 
    } 

private: 
    T m_Data; 
    CType::eType GetType(); 
}; 

template<> CType::eType CData<int>::GetType() { return TYPE_NUMBER; }; 
template<> CType::eType CData<string>::GetType() { return TYPE_STRING; }; 

int main() 
{ 
    cout << "Hello world!" << endl; 

    CData<int> cd_int(5); 
    CData<string> cd_str("SO contribution"); 

    list<CType> my_list = { cd_int, cd_str }; 

    for (auto & elem : my_list) 
     cout << elem.GetStringVal() << endl; 

    return 0; 
} 
관련 문제