2010-06-05 5 views
3

지도에 여러 변수와지도가 포함 된 구조체를 만들 수 있는지 궁금합니다.지도에지도가 포함 된 구조체? (C++/STL)

내가 지금 무엇을 가지고 :

typedef std::map<std::string,double> lawVariables; 

struct ObjectCustomData { 
    std::string objectType;  
    bool global_lock; 
    std::map<std::string, lawVariables> lawData; 
}; 

이 구조체는 그 객체에 대한 하나의 데이터 블록으로 다른 함수에 전달됩니다. 다음과 같이

구조 설정은 다음과 같습니다의 개체 유형, 잠금에 대한 부울,이 같이 볼 수 있었다 "법률"의 다양한 수 :

law1 -> var_a = 39.3; 
    -> var_g = 8.1; 
law8 -> var_r = 83.1; 
    -> var_y = 913.3; 
    -> var_a = 9.81; 
각 객체가 포함 된 데이터 블록을 가지고

첫 번째로 Map 내에서 Map을 사용해야하는지 확신 할 수 없지만 둘째로 이것이 유효하더라도 데이터로 채우는 방법과 이후에이를 다시 호출하는 방법을 확신 할 수 없습니다. 특정 물체에 특정 법칙이 있는지, 그리고 그 법칙에 특정 변수가 있는지를 검색 할 수 있기 때문에지도를 살펴 보았습니다.

답변

2

I was wondering if it was possible to create a struct containing a number of variables and a map in a map

(첫 번째 지저분한 포스트 외관 미안,이 :) 더 나은 희망). 다른 맵 안에 Map을 값으로 가질 수 있습니다. 지금 당신의 편집을 보았다 :

typedef std::vector<std::pair<std::string,double> > lawVariables; 

struct ObjectCustomData { 
    std::string objectType;  
    bool global_lock; 
    std::map<std::string, lawVariables> lawData; 
}; 

편집 : 당신이 삽입의 순서를 고집하고 항목이 내부지도 적은 경우처럼

는 데이터 구조는 수 보인다. 조회가 기본 요구 사항 인 경우지도를 찾으십시오.

예 :

typedef std::map<std::string,double> lawVariables; 

    struct ObjectCustomData { 
     std::string objectType;  
     bool global_lock; 
     std::map<std::string, lawVariables> lawData; 
    }; 

void test(ObjectCustomData& data) 
{ 
    lawVariables& variable = data.lawData["law_1"]; 
    variable["var_a"] = 39.3; 

} 
+1

@aJ - 테스트 메소드를 컴파일하려고하면 'data [ "law_1"]'에서 'error : no match'연산자 [] '가 발생합니다. 사용자를 대신하여 컴파일합니까? g ++ 컴파일러를 사용하고 있습니다. cygwin에서 – dcp

+1

죄송합니다. 첫 번째 줄은 data.lawData [ "law_1"]이어야합니다. pls는 내 편집을 참조하십시오. –

+0

답장을 보내 주셔서 감사합니다. : D – Karrok

1

당신이 일을해야 무엇을 가지고. 당신은 다음과 같은 데이터를로드 할 수

ObjectCustomData data; 
    data.lawData["law_1"]["var_a"] = 39.3; 
    data.lawData["law_1"]["var_g"] = 8.1; 
    data.lawData["law_8"]["var_r"] = 83.1; 
    . 
    . 
    . 

당신은이 같은 요소의 존재를 확인 할 수 있습니다

if (!data.lawData.count("law_x")) { 
    cout<<"law_x not found"<<endl; 
    } 

    if (data.lawData.count("law_1")) { 
    cout<<"law_1 was found"<<endl; 
    } 
+0

요소 존재 여부를 확인하는 코드가 잘못되었습니다. 코드를 입력하지 마십시오. "law_x"키가 없으면 빈지도를 만든 다음 크기를 쿼리하면 문자열 할당,지도 작성 등을 의미합니다 std :: map :: find를 사용하는 것이 더 낫다 – utnapistim

+0

@utnapistim - 좋은 지적, 의견을 보내 주셔서 감사합니다. 실제로 카운트 inste 사용하는 것이 좋습니다. 조금 깨끗한 IMO이기 때문에 찾기 광고. 내 대답을 업데이트했습니다. – dcp

0

그냥 다음은 aswell에 대한 넣다 다른 사람이보고 될 수 있습니다 추가 : (참고, 그 중 일부는 사용되지 갈 정도 알려 주시기 바랍니다 있습니다 :)) .H에

!

typedef std::map<std::string,double> lawVariables; 
typedef std::map<std::string,double>::iterator lawVars; 
struct ObjectCustomData { 
    std::string objectType; 
    bool global_lock; 
    std::map<std::string, lawVariables> lawData; 
}; 


template <typename K, typename V, class C, class A> 
std::ostream &operator<< (std::ostream &os, std::map<K,V,C,A> const& m) 
{ 
    os << "{ "; 
    typename std::map<K,V,C,A>::const_iterator p; 
    for (p = m.begin(); p != m.end(); ++p) { 
     os << p->first << ":" << p->second << ", "; 
    } 
    return os << "}"; 
} 

참고 : 템플릿 소재이므로 전체지도 인지도를 간단하게 작성할 수 있습니다.

void setCustomData(); 
    void showCustomData(); 
    bool checkLaw(std::string law); 
    bool checkVar(std::string law,std::string var); 
    double getLawVar(std::string law, std::string var); 
    template<class T,class A> 
    void showMap(const std::map<T, A>& v); 
    ObjectCustomData ocd; 

참고 : 그냥 맵에서 맵 테스트 목적을 위해 어떤 임의의 데이터를 채우는 것 setCustomData는 showCustomData는 전체지도를 보여 템플릿 및 사용자 정의 연산자를 사용합니다. checkLaw와 checkVar는 특정 값이 존재 하는지를 확인하고 getLawVar는 특정 법의 특정 값의 값을 반환합니다. showMap은 map-in-map의 전체 내용을 다소 좋은 출력으로 보여줍니다.

cpp :

아뇨, setCustomData를 건너 뛰십시오. ocd.lawData [law] [var] = 123.45;

void showCustomData() { 
     std::cout <<ocd.lawData<<std::endl; 
    } 
    bool checkLaw(std::string law){ 
     if ((int)ocd.lawData[law].size() != 0) { 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 
    bool checkVar(std::string law, std::string var){   
     lawVars lVars = ocd.lawData[law].find(var); 
     if(lVars != ocd.lawData[law].end()){ 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 
    double getLawVar(std::string law, std::string var){ 
     if (checkLaw(law) && checkVar(law, var)){ 
      return ocd.lawData[law].find(var)->second; 
     } 
     else {return 0.0;} 
    } 
    template<class T, class A> 
    void showMap(const std::map<T, A>& v) { 
     for (std::map<T, A>::const_iterator ci = v.begin(); ci != v.end(); ++ci) { 
      std::cout << ci->first <<" -> "; 
      lawVariables tmpLaw = ci->second; 
      lawVars lVars; 
      for (lVars = tmpLaw.begin(); lVars != tmpLaw.end(); lVars++){ 
       std::cout << lVars->first << " : " << lVars->second <<"\t"; 
      } 
      std::cout<<std::endl; 
     } 
     std::cout<<std::endl; 
    } 

희망 사항은 누군가에게 다소 유용 할 것입니다. 할 수있는 일에 대해 자유롭게 의견을 말하십시오.

+1

이 코드에서 값으로 전달되는 모든 문자열과 맵은 const 참조로 전달되어야합니다. 또한 const 멤버 함수의 개념을 조사해야합니다. –

+0

자바의 해 : Karrok

관련 문제