2014-06-16 4 views
2

내가이 맵에 삽입하려고 :이있어C++ 부울 표준 : 운영자 키 표준지도와 <오류 :: unordered_set <INT, 표준 : 해시 <int>>

std::map<std::unordered_set<int >, std::pair<float, std::pair<float, float >> >

오류

오류 C2784 : '부울 표준 : 운영자 < (const를 표준 : _ 트리 < _Traits> &, const를 표준 : _ 트리 < _Traits> &가) : CONST 표준 : _ _Traits> & '에서'const를 표준 : unordered_set, 표준 : equal_to < _Kty>, 표준 : : 할당 < _Kty >> '

트리 <을' 에 대한 템플릿 인수를 추론 할 수 없었다 '
내 데이터로 정의

은 다음 :

struct Trans { 
    int Item; 
    float Prob; 
    float W; 
}; 
bool operator<(const Trans &a, const Trans &b) 
    { 
     return a.Item < b.Item; 
    } 
    bool operator==(Trans c, Trans d) { return c.Item == d.Item; } 


    struct MyHash { 
     size_t operator()(const Trans& x) const { return std::hash<int>()(x.Item); } 
    }; 


std::vector<std::vector<Trans>> data; 
std::map<std::unordered_set<int>, float> S1; 
std::map<std::unordered_set<int >, std::pair<float, std::pair<float, float >> > S2; 
std::map<std::unordered_set<int >, std::pair<float, std::pair<float, float >> > S3; 

문제가 부분 :

do 
     { 

std::unordered_set<Trans, MyHash> KS(data[i].begin(), data[i].begin() + k); 
std::unordered_set<int > elem; 

float esupp = 1; 
float Weight = 0; 
float Wesupp = 1; 
    for (auto const &iter : KS) 
     { 
      elem.insert(iter.Item); 
      esupp *= iter.Prob; 
      Weight += iter.W; 
     } 
     Weight = Weight/k; 


     /* 
     some code, and until here I didn't get any problem 
     */ 

      **// This the area that has the problem** 

    S1[elem] = std::move(S1[elem] + esupp); 
    Wesupp = Weight * S1[elem]; 
    S2[elem].first = std::move(S2[elem].first + esupp); 
    S2[elem].second = std::make_pair(elem, Wesupp); 
    } while (next_combination(data[i].begin(), data[i].begin() + k, data[i].end())); 
+0

오류가있는 실제 행은 무엇입니까? –

+0

나머지 부분을 제외하고,이 줄은 옳지 않습니다 :'S2 [elem] .second = std :: make_pair (elem, Wesupp); ' –

+1

데이터 구조 디자인 ...'unordered_set'을 키로서 심각하게 재검토하겠습니까? 'std :: pair >'? '[elem] = std :: move (S1 [elem] + esupp)''에서'S2 [elem] (적어도'std :: tuple' 또는'std :: array ') –

답변

1

std::map은 비교기가 제공되지 않는 한 해당 키가 < 연산자를 구현해야합니다.

키 유형이 std::unordered_set 인 경우 "미만"을 구현하지 않습니다.

@ T.C. 당신은 std::unordered_set 대신 std::set을 사용할 수 있습니다.

+0

감사합니다. 그러나'std :: map'을'std :: unordered_map'으로 대체하면'오류 C2338 : C++ 표준은이 유형의 해시를 제공하지 않습니다. ' – Sandy

+0

@Sandy I' 그 때 제안을 삭제할 것입니다. 오류의 원인은 동일합니다. C++은 그것을 지원하지 않습니다. –

+0

'std :: set'은 표준에 정의 된'operator <()'를 가지고 있습니다. –

1

Drew Dormann이 지적한대로 현재의 오류는 std::unordered_setoperator < 부재로 인한 것입니다.

std::set 그러나 오버로드 된 operator <이 있으므로 사용할 수 있습니다.

코드의 문제는 그보다 더 깊게 실행됩니다. 예를 들어 :

S1[elem] = std::move(S1[elem] + esupp); 

당신은 float를 할당한다. std::move을 사용하는 데는 아무런 의미가 없습니다. 특히 S1[elem] + esupp은 이미 r 값입니다. 이 줄을 작성하는 일반적인 방법은 S1[elem] += esupp;

S2[elem].first = std::move(S2[elem].first + esupp); 

같은 문제 일 수 있습니다.

S2[elem].second = std::make_pair(elem, Wesupp); 

할당의 LHS는 std::pair<float, float>입니다. RHS는 std::pair<std::unordered_set<int>, float>을 만듭니다.

그리고 내가 코멘트에서 언급했듯이 std::pair<float, std::pair<float, float>>은 나쁜 디자인 일뿐입니다. 적어도 std::tuple이거나 심지어는 std::array<float, 3>이거나 3 개의 부동 소수점이 실제로 의미하는 것을 명확하게하는 단순한 구조체 여야합니다.

지도에 키로 set<int> (정렬되지 않거나 정렬되지 않음)을 사용하는 것은 상당히 이상한 디자인입니다. 반복 할 수있는 set<int> -3x float 쌍의 목록을 유지 관리 하시겠습니까, 아니면 실제로 set<int>으로 효율적으로 색인을 생성하고 싶습니까? 효율적인 색인 생성이 필요하지 않은 경우지도가 아닌 쌍의 벡터를 사용하십시오.

+0

영어가 제 첫 번째 언어가 아니기 때문에 S2를 설명하기 위해 예제를 사용했습니다. 시간을 가져 보시기 바랍니다. http://im67.gulfup.com/REB8Fj.png – Sandy