2013-08-02 2 views
4

좌표를 키로 사용하여 std :: map을 만드는 것은 불가능합니다. (x + y + z)가 두 좌표에서 동일 할 경우 맵은 이전 좌표를 무시합니다. 예 :좌표가 키로 설정된 std :: map 만들기

map[Coordinate(1, 0, 0)] = object1; 
map[Coordinate(0, 1, 0)] = object2; 
map[Coordinate(0, 0, 1)] = object3; 

이이 값 object3 키 등을 포함 Coordinate(0, 0, 1) 1 개 요소와 표준 :지도 당할 것이다. 이것을 방지하여 모든 값을 포함 할 수 있습니까?

#pragma once 

struct Coordinate { 
    double x, y, z; 
    Coordinate(double x, double y, double z) : x(x), y(y), z(z) {} 

    bool operator<(const Coordinate& coord) const { 
    if(x + y + z < coord.x + coord.y + coord.z) 
     return true; 
    return false; 
    } 

    bool operator==(const Coordinate& coord) const { 
     if(x == coord.x && y == coord.y && z == coord.z) 
      return true; 
     return false; 
    } 

    inline bool isInRange(Coordinate coord, int range) const { 
     if(pow(coord.x - this->x, 2) + pow(coord.y - this->y, 2) + pow(coord.z - this->z, 2) <= range*range) 
      return true; 
     return false; 
    } 
}; 
+1

http://stackoverflow.com/questions/1380567/can-i-use-an-stl-map-if-i-plan-to-use-arbitrary-class- objects-as-the-key 대답 읽기 – UnknownError1337

+0

당신의 문제는 당신의'<'연산자가 결정적이어야한다는 것입니다. '(x + y + z Joe

+0

1 차원 <연산자를 사용할 때 같기 때문입니다. –

답변

5

«표준 : 맵은 키 - 값을 고유 키와 쌍을 포함하는 정렬 연관 컨테이너입니다. 키는 비교 비교 기능을 사용하여 정렬됩니다. cppreference

에서 기본 비교 함수를»은 Key 개체에 대한 연산자 <를 사용합니다 std::less입니다.

따라서, 문제는 operator<Coordinate의에있다 :

bool operator<(const Coordinate& coord) const { 
if(x + y + z < coord.x + coord.y + coord.z) 
    return true; 
return false; 
} 

(1, 0, 0) < (0, 1, 0)은 false입니다 만 (0, 1, 0) < (1, 0, 0) 지금까지 std::map(1, 0, 0) == (0, 1, 0)을 우려하고있다, 또한 거짓입니다. std::map에 키와 Coordinate 객체를 사용하기 위해

, 당신은 당신의 요구에 맞는 올바른 엄격한 약한 주문 기준합니다 (operator<)를 찾아야합니다. 다른 말했다

, 당신이 먼저 x을 비교합니다 (C++ 11) std::tie 같은,이 같은 y 다음 z 사용할 수 있습니다 비교의 목적을 위해

bool operator<(const Coordinate& coord) const { 
    if(x < coord.x) return true; 
    if(x > coord.x) return false; 
    //x == coord.x 
    if(y < coord.y) return true; 
    if(y > coord.y) return false; 
    //x == coord.x && y == coord.y 
    if(z < coord.z) return true; 
    if(z > coord.z) return false; 
    //*this == coord 
    return false; 
} 
+0

문제의 좋은 설명입니다. 보너스 포인트는 더 나은 주문을 제안 할 수 있습니까? –

+0

문제가 해결되지 않습니다. –

+0

좌표 정렬은 실제로 이해가되지 않지만 엄격한 순서를 얻기 위해 std :: tie (x, y, z) undu

-1

을하는 std::map는 것이다 ab 두 개체를 동일하다고 간주하는 경우 !(a < b) && !(b < a). operator<은 그러한 모호성을 정확하게 만듭니다. 먼저 (1, 0, 0)을 키로 삽입하십시오. 다음에는 (0, 1, 0)을 삽입하여 비교합니다. 그러나 연산자를 사용하는 경우 (1, 0, 0) < (0, 1, 0)false을 반환하고 (0, 1, 0) < (1, 0, 0)도 반환하므로 두 좌표가 동일한 키에 매핑됩니다.

+0

기능을 해킹하지 않고 수정할 방법이 없습니까? –

+0

@Binero 모든 좌표를 엄격하게 정렬 할 수 있도록 명령이 내려집니다. 예를 들어, 모든 구성 요소의 합이 동일하다면, 가장 큰 'x'를 가진 것이 더 크고, 다음에 동등한 경우 'y'가오고, 가장 큰 'z'가있는 마지막 하나가 나온다고 말하십시오. – DUman

2

귀하의 운영자 < 가능한 모든 좌표가 안정된 순서로 배치 될 수 있도록 작업해야합니다. 값을 추가하면 좌표를 서로 구별 할 수없는 몇 가지 조합이 있습니다.

보십시오이

friend bool operator < (const Coordinate& left, const Coordinate& right) 
{ 
    if (left.z < right.z) 
    { 
     return true; 
    } 
    else if (right.z < left.z) 
    { 
     return false; 
    } 
    else if (left.y < right.y) 
    { 
     return true; 
    } 
    else if (right.y < left.y) 
    { 
     return false; 
    } 
    else if (left.x < right.x) 
    { 
     return true; 
    } 
    else /* (right.x < left.x) */ 
    { 
     return false; 
    } 
} 
+0

이 isn 그래도 돌아 가야 할 것 같아. 이것은 기본적으로지도를 속이는 것입니다. –

+2

또는 C++ 11에서'return std :: tie (l.x, l.y, l.z)

+0

@MikeSeymour 이전에 본 적이 없습니다. –